home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-10-25 | 135.5 KB | 5,255 lines | [TEXT/MPS ] |
- {$P}
- {[a-,body+,h-,o=100,r+,rec+,t=4,u+,#+,j=20/57/1$,n-]}
- { UCalc.inc1.p}
- { Copyright © 1985 - 1990 by Apple Computer, Inc. All rights reserved. }
-
- CONST
- kTextScrapType = 'TEXT';
- kCalcScrapType = 'CALC';
-
- kCellWidth = 80; { default width of each cell }
- kCellHeight = 17; { default height of each cell }
- kCellHBorder = 2; { pixels separating cell contents from
- left/right edge }
-
- kCellFont = applFont;
- kCellFontSize = 10;
- kRowTitleWidth = 32; { width of row titles }
- kColumnTitleHeight = 20; { height of column titles }
- kTitlesFont = applFont; { font for column/row titles }
- kTitlesFontSize = 10; { font size for column/row titles }
-
- kEntryFont = applFont; { default font of cell contents }
- kEntryFontSize = 10; { default font size of cell contents }
- kEntryHeight = 20; { height of the cell entry view }
-
- kCalcMode = Automatic; { default calculation mode }
- kForceAutomatic = TRUE; { force automatic calculation }
- kSetDependents = TRUE; { set cell's dependents }
-
- kDefaultJustification = TEJustCenter; { default cell justification }
- kNoJustification = 2; { constant representing no justification }
-
- kValuePrecision = 18; { digits of precision in our values }
- kTELength = (80 * 5); { number of characters in the text edit
- field }
-
- { Command Constants }
-
- cPrintSelection = 180;
- cRecalculate = 401;
- cAutoCalc = 403;
- cManualCalc = 404;
- cGeneral = 501;
- cNoDecimal = 503;
- cDecimal = 504;
- cScientific = 505;
- cSystemJustify = 506;
- cForceLeftJustify = 507;
- cRightJustify = 508;
- cCenter = 509;
- cSelection = 1000;
- cSizeColumn = 1001;
- cCutText = 1103;
- cCopyText = 1104;
- cClearText = 1106;
- cCutCells = 1203;
- cCopyCells = 1204;
- cClearCells = 1206;
- cStandardCut = 1303;
- cStandardCopy = 1304;
- cStandardClear = 1306;
-
- { Cursor Resource ID's }
-
- kColumnSizingCursor = 256; { cursor for resizing a column }
- kRowSizingCursor = 257; { cursor for resizing a row--UNUSED }
-
- TYPE
- TypeOfLine = (NoLine, { for DrawLine routine}
- SolidLine, BoldLine, VDottedLine, HDottedLine, RowSeparator,
- ColumnSeparator);
-
- VAR
- gGeneralFormat: ValueFormat; { SANE conversion formats }
- gDecimalFormat: ValueFormat;
- gNoDecimalFormat: ValueFormat;
- gScientificFormat: ValueFormat;
- gNoFormat: ValueFormat;
- gDefaultFormat: FormatRecord; { default cell format }
-
- gColumnSeparatorPattern: Pattern; { patterns for separator lines }
- gRowSeparatorPattern: Pattern;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AFields}
-
- PROCEDURE FormatFields(aTitle: Str255;
- VAR aFormat: FormatRecord;
- PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER));
-
- VAR
- aString: Str255;
- anInteger: INTEGER;
- aStyle: Style;
-
- BEGIN
- { Because our brain-damaged compiler won't allow you to pass the address of byte-aligned
- fields in packed records, we have to move the fields of a FormatRecord into a temporary
- variable, then pass the address of the temporary. }
-
- DoToField(aTitle, NIL, bTitle);
- WITH aFormat DO
- BEGIN
- CASE aFormat.fStyle OF
- NoStyle:
- aString := 'NoStyle';
- General:
- aString := 'General';
- DecimalStyle:
- aString := 'DecimalStyle';
- NoDecimal:
- aString := 'NoDecimal';
- Scientific:
- aString := 'Scientific';
- OTHERWISE
- aString := 'UnknownStyle';
- END;
- DoToField(' fStyle', @aString, bString);
-
- anInteger := fDigits;
- DoToField(' fDigits', @anInteger, bInteger);
-
- CASE fJustification OF
- teJustSystem:
- aString := 'System';
- teForceLeft:
- aString := 'Forced Left';
- TEJustCenter:
- aString := 'Center';
- TEJustRight:
- aString := 'Right';
- kNoJustification:
- aString := 'None';
- OTHERWISE
- aString := 'Unknown';
- END;
- DoToField(' fJustification', @aString, bString);
-
- anInteger := fFontNumber;
- DoToField(' fFontNumber', @anInteger, bFontName);
- anInteger := fFontSize;
- DoToField(' fFontSize', @anInteger, bInteger);
- aStyle := fFontStyle;
- DoToField(' fFontStyle', @aStyle, bStyle);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AReadFile}
-
- PROCEDURE ReadCellCoordinate(theRefNum: INTEGER;
- VAR r: RowNumber;
- VAR c: ColumnNumber);
- { Reads a cell coordinate from a file }
-
- VAR
- cellCoordinate: Point;
-
- BEGIN
- ReadBytes(theRefNum, SIZEOF(cellCoordinate), @cellCoordinate);
- r := cellCoordinate.v;
- c := cellCoordinate.h;
- END;
-
- {***************************************************************************************************
- T C a l c A p p l i c a t i o n
- ***************************************************************************************************}
- {$S AInit}
-
- PROCEDURE TCalcApplication.ICalcApplication(itsFileType: OSType);
-
- BEGIN
- IApplication(itsFileType);
-
- gGeneralFormat.Style := FloatDecimal;
- gGeneralFormat.digits := kValuePrecision;
-
- gDecimalFormat.Style := FixedDecimal;
- gDecimalFormat.digits := 2;
-
- gNoDecimalFormat.Style := FixedDecimal;
- gNoDecimalFormat.digits := 0;
-
- gScientificFormat.Style := FloatDecimal;
- gScientificFormat.digits := 2;
-
- gNoFormat.Style := FixedDecimal;
- gNoFormat.digits := - 1;
-
- gDefaultFormat.fJustification := kDefaultJustification;
- gDefaultFormat.fStyle := General;
- gDefaultFormat.fDigits := 0;
- gDefaultFormat.fFontNumber := kCellFont;
- gDefaultFormat.fFontSize := kCellFontSize;
- gDefaultFormat.fFontStyle := [];
-
- gColumnSeparatorPattern := gray;
- gRowSeparatorPattern := gray;
-
- { Suppress Linker dead-stripping of these classes }
- IF gDeadStripSuppression THEN
- BEGIN
- IF Member(TObject(NIL), TCalcWindow) THEN;
- IF Member(TObject(NIL), TCellsView) THEN;
- IF Member(TObject(NIL), TRowsView) THEN;
- IF Member(TObject(NIL), TColumnsView) THEN;
- IF Member(TObject(NIL), TEntryView) THEN;
- IF Member(TObject(NIL), TCoordView) THEN;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCalcApplication.AboutToLoseControl(convertClipboard: BOOLEAN); OVERRIDE;
- { Remove Edit menu buzzwords for incoming Desk Accessory }
-
- BEGIN
- SetEditCmdName(cCut, cStandardCut);
- SetEditCmdName(cCopy, cStandardCopy);
- SetEditCmdName(cClear, cStandardClear);
-
- INHERITED AboutToLoseControl(convertClipboard);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AOpen}
-
- FUNCTION TCalcApplication.DoMakeDocument(itsCmdNumber: cmdNumber): TDocument;
-
- VAR
- aCalcDocument: TCalcDocument;
- dimensions: Rect;
-
- BEGIN
- { Allocate and initialize the document}
- NEW(aCalcDocument);
- FailNIL(aCalcDocument);
- SetRect(dimensions, 1, 1, kMaxColumns, kMaxRows);
- aCalcDocument.ICalcDocument(dimensions);
- DoMakeDocument := aCalcDocument;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AClipboard}
-
- FUNCTION TCalcApplication.MakeViewForAlienClipboard: TView; OVERRIDE;
- { Launch a view to represent the data found in the Clipboard at
- application start-up time, or when returning from an excursion
- to MultiFinder, or when returning from a Desk Accessory. This
- creates a clipboard for 'CALC' scrap. }
-
- VAR
- calcScrap: Handle;
- scrapOffset: LONGINT;
- clipDocument: TCalcDocument;
- clipView: TCellsView;
- scrapInfo: ScrapInfoRecord;
- r: RowNumber;
- c: ColumnNumber;
- i: INTEGER;
- cellsRead: INTEGER;
- cellCoord: Point;
- offset: LONGINT;
- aRow: TRow;
- aColumn: TColumn;
- aCell: TCell;
- perm: BOOLEAN;
- fi: FailInfo;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE HdlScrapFailure(error: OSErr;
- message: LONGINT);
-
- BEGIN
- calcScrap := DisposeIfHandle(calcScrap);
-
- FreeIfObject(clipDocument);
- clipDocument := NIL;
- END;
-
- BEGIN
- { Before doing anything else, make sure the scrap contains my type }
- IF GetScrap(NIL, kCalcScrapType, offset) > 0 THEN
- BEGIN
- clipDocument := NIL; { so failure handler knows to free it }
- calcScrap := NIL;
-
- CatchFailures(fi, HdlScrapFailure);
-
- calcScrap := NewPermHandle(0);
- FailNIL(calcScrap);
-
- perm := PermAllocation(TRUE);
- scrapOffset := GetScrap(calcScrap, kCalcScrapType, offset);
- perm := PermAllocation(perm);
-
- { Only a negative result indicates an error--FailOSErr considers any non-zero result an error. }
- IF scrapOffset < 0 THEN
- FailOSErr(scrapOffset);
- scrapOffset := 0;
-
- ReadScrap(calcScrap, scrapOffset, @scrapInfo, SIZEOF(scrapInfo));
- FailMemError;
- NEW(clipDocument);
- FailNIL(clipDocument);
- clipDocument.ICalcDocument(scrapInfo.selection);
- clipDocument.DoInitialState;
-
- NEW(clipView);
- FailNIL(clipView);
- clipView.ICellsView(clipDocument, TRUE, NIL);
- clipDocument.fCellsView := clipView;
-
- FOR r := 1 TO clipDocument.fNoOfRows DO
- BEGIN
- NEW(aRow);
- aRow.ReadFromScrap(calcScrap, scrapOffset);
- clipDocument.AddRow(aRow);
- END;
-
- FOR c := 1 TO clipDocument.fNoOfColumns DO
- BEGIN
- NEW(aColumn);
- aColumn.ReadFromScrap(calcScrap, scrapOffset);
- clipDocument.AddColumn(aColumn);
- END;
-
- cellsRead := 0;
- FOR i := 1 TO scrapInfo.noOfCells DO
- BEGIN
- ReadScrap(calcScrap, scrapOffset, @cellCoord, SIZEOF(cellCoord));
- aCell := clipDocument.GetCell(cellCoord.v, cellCoord.h);
- aCell.ReadFromScrap(calcScrap, scrapOffset);
- cellsRead := cellsRead + 1;
- END;
-
- {$IFC qDebug}
- IF gIntenseDebugging THEN
- BEGIN
- WRITELN('MakeViewForAlienClipboard: cellsRead=', cellsRead: 0, ', scrapInfo.noOfCells=',
- scrapInfo.noOfCells);
- IF cellsRead <> scrapInfo.noOfCells THEN
- ProgramBreak('MakeViewForAlienClipboard: Wrong number of cells');
- END;
- {$ENDC}
-
- calcScrap := DisposeIfHandle(calcScrap);
-
- Success(fi);
- MakeViewForAlienClipboard := clipView;
- END
- ELSE
- MakeViewForAlienClipboard := INHERITED MakeViewForAlienClipboard;
- END;
-
- {***************************************************************************************************
- T C a l c D o c u m e n t
- ***************************************************************************************************}
- {$S AOpen}
-
- PROCEDURE TCalcDocument.ICalcDocument(dimensions: Rect);
-
- VAR
- r: RowNumber;
- c: ColumnNumber;
- aRect: Rect;
-
- BEGIN
- IDocument(kFileType, kSignature, kUsesDataFork, NOT kUsesRsrcFork, NOT kDataOpen,
- NOT kRsrcOpen);
-
- fSavePrintInfo := TRUE; { the 'print info' record of the
- fDocPrintHandler will be written out to
- the data fork }
-
- fDimensions := dimensions;
- WITH dimensions DO
- BEGIN
- fRowOffset := top - 1;
- fColumnOffset := left - 1;
- fNoOfRows := bottom - top + 1;
- fNoOfColumns := right - left + 1;
- END;
- fCalcMode := kCalcMode;
- fSelectionType := NoSelection;
-
- fCellsView := NIL;
- fRowsView := NIL;
- fColumnsView := NIL;
- fEntryView := NIL;
- fCoordView := NIL;
-
- fEditRow := 0;
- fEditColumn := 0;
- fEditCell := NIL;
-
- { Initialize cells, rows and columns }
- FOR r := 1 TO fNoOfRows DO
- BEGIN
- fRows[r] := NIL;
- FOR c := 1 TO fNoOfColumns DO
- BEGIN
- fCells[r, c] := NIL;
- END;
- END;
-
- FOR c := 1 TO fNoOfColumns DO
- fColumns[c] := NIL;
-
- SetRect(aRect, 1, 1, 1, 1);
- fInUseBounds := aRect;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AClose}
-
- PROCEDURE TCalcDocument.Free;
-
- BEGIN
- FreeData;
-
- INHERITED Free;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCalcDocument.AddCell(theCell: TCell;
- r: RowNumber;
- c: ColumnNumber);
-
- VAR
- aRect: Rect;
-
- BEGIN
- fCells[r, c] := theCell;
- fAllocatedCells := fAllocatedCells + 1;
-
- SetRect(aRect, c, r, c, r);
- {$Push} {$H-}
- UnionRect(aRect, fInUseBounds, fInUseBounds);
- {$Pop}
-
- WITH theCell DO
- BEGIN
- fCalcDocument := SELF;
- fRow := r;
- fColumn := c;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCalcDocument.AddColumn(theColumn: TColumn);
-
- BEGIN
- fColumns[theColumn.fNumber] := theColumn;
- fAllocatedColumns := fAllocatedColumns + 1;
-
- fInUseBounds.left := Min(fInUseBounds.left, theColumn.fNumber);
- fInUseBounds.right := Max(fInUseBounds.right, theColumn.fNumber);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCalcDocument.AddRow(theRow: TRow);
-
- BEGIN
- fRows[theRow.fNumber] := theRow;
- fAllocatedRows := fAllocatedRows + 1;
-
- fInUseBounds.top := Min(fInUseBounds.top, theRow.fNumber);
- fInUseBounds.bottom := Max(fInUseBounds.bottom, theRow.fNumber);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- FUNCTION TCalcDocument.CellExists(r: RowNumber;
- c: ColumnNumber): BOOLEAN;
-
- BEGIN
- CellExists := (r > 0) & (r <= kMaxRows) & (c > 0) & (c <= kMaxColumns) & (fCells[r, c] <> NIL) &
- (NOT fCells[r, c].fDeleted);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- FUNCTION TCalcDocument.CellInRange(r: INTEGER;
- c: INTEGER;
- range: Rect): BOOLEAN;
-
- BEGIN
- WITH range DO
- CellInRange := (r >= top) & (r <= bottom) & (c >= left) & (c <= right);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- FUNCTION TCalcDocument.ColumnExists(c: ColumnNumber): BOOLEAN;
-
- BEGIN
- ColumnExists := (c > 0) & (c <= kMaxColumns) & (fColumns[c] <> NIL);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCalcDocument.ConstrainToUsedCells(VAR cellRange: Rect);
- { Given a range of cells, this returns the range of cells that fall
- within the range of used cells. This is used to optimize
- performance so that we don't try to operate on cells that
- we know have never been used (i.e. allocated). }
-
- BEGIN
- WITH cellRange DO
- BEGIN
- top := Max(top, fInUseBounds.top);
- left := Max(left, fInUseBounds.left);
- bottom := Min(bottom, fInUseBounds.bottom);
- right := Min(right, fInUseBounds.right);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCalcDocument.DeleteCell(r: RowNumber;
- c: ColumnNumber);
-
- VAR
- theCell: TCell;
-
- BEGIN
- theCell := GetExistingCell(r, c);
- IF theCell <> NIL THEN
- BEGIN
- theCell.SetDeleteState(TRUE);
- fAllocatedCells := fAllocatedCells - 1;
- IF theCell = fEditCell THEN
- fEntryView.SetToString('');
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AOpen}
-
- PROCEDURE TCalcDocument.DoInitialState; OVERRIDE;
-
- BEGIN
- fAllocatedCells := 0;
- fAllocatedRows := 0;
- fAllocatedColumns := 0;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AOpen}
-
- PROCEDURE TCalcDocument.DoMakeViews(forPrinting: BOOLEAN);
-
- VAR
- aCalcWindow: TCalcWindow;
- aTEntryView: TEntryView;
- aCellsView: TCellsView;
- aColumnsView: TColumnsView;
- aRowsView: TRowsView;
- aCoordView: TCoordView;
- aRowScroller: TSecondaryScroller;
- aColumnScroller: TSecondaryScroller;
- aCalcScroller: TPrimaryScroller;
- aPrintHandler: TCalcPrintHandler;
-
- PROCEDURE SetColumnWidths;
-
- VAR
- c: ColumnNumber;
- newWidth: INTEGER;
-
- BEGIN
- FOR c := 1 TO fNoOfColumns DO
- IF fColumns[c] <> NIL THEN
- BEGIN
- newWidth := fColumns[c].fWidth;
- IF newWidth <> kCellWidth THEN
- BEGIN
- fCellsView.SetColWidth(c, 1, newWidth);
- fColumnsView.SetColWidth(c, 1, newWidth);
- END;
- END;
- END;
-
- BEGIN
- aCalcWindow := TCalcWindow(NewTemplateWindow(kCalcWindowType, SELF));
- WITH aCalcWindow DO
- BEGIN
- aCellsView := TCellsView(FindSubView('CELL'));
- aRowsView := TRowsView(FindSubView('ROWS'));
- aColumnsView := TColumnsView(FindSubView('COLS'));
- aTEntryView := TEntryView(FindSubView('ENTV'));
- aCoordView := TCoordView(FindSubView('CORD'));
- END;
-
- fCellsView := aCellsView;
- fRowsView := aRowsView;
- fColumnsView := aColumnsView;
- fEntryView := aTEntryView;
- fCoordView := aCoordView;
-
- IF NOT forPrinting THEN
- BEGIN
- aTEntryView.fText := NewPermHandle(0);
- FailNIL(aTEntryView.fText);
- aTEntryView.StuffText(aTEntryView.fText); { Stuff the initial text in }
- END;
-
- { Insert the entry view between the cell's view and its scroller in the target chain }
- aCalcWindow.SetTarget(aCellsView);
- aTEntryView.fNextHandler := aCellsView.fNextHandler;
- aCellsView.fNextHandler := aTEntryView;
-
- { set up the cells view scroller to scroll the rows and columns too }
- aCalcScroller := TPrimaryScroller(aCellsView.GetScroller(TRUE));
- aCalcScroller.SetScrollParameters(kCellWidth, kCellHeight, TRUE, TRUE);
-
- aColumnScroller := TSecondaryScroller(aColumnsView.GetScroller(TRUE));
- aColumnScroller.SetScrollParameters(kCellWidth, 0, TRUE, TRUE);
-
- aRowScroller := TSecondaryScroller(aRowsView.GetScroller(TRUE));
- aRowScroller.SetScrollParameters(0, kCellHeight, TRUE, TRUE);
-
- aCalcScroller.AddSecondaryScroller(aRowScroller, kNotHDependent, kVDependent);
- aCalcScroller.AddSecondaryScroller(aColumnScroller, kHDependent, kNotVDependent);
-
- NEW(aPrintHandler);
- FailNIL(aPrintHandler);
- aPrintHandler.IStdPrintHandler(SELF, { its document }
- aCellsView, { its view }
- NOT kSquareDots, { does not have square dots }
- NOT kFixedSize, { horizontal page size is variable }
- kFixedSize); { vertical page size is fixed }
- aPrintHandler.fMinimalMargins := FALSE;
-
- SetColumnWidths; { get existing document's column widths }
-
- IF forPrinting THEN { Finder printing }
- aPrintHandler.RedoPageBreaks
- ELSE
- BEGIN
- ShowReverted; { display the views }
-
- fEditRow := 1; { default cell to edit is A1 }
- fEditColumn := 1;
- SetEntry(fEditRow, fEditColumn);
- fSelectionType := CellSelection;
- fCellsView.SelectCell(GridCell($00010001), kDontExtend, kDontHighlight, kSelect);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ASelCommand}
-
- FUNCTION TCalcDocument.DoMenuCommand(aCmdNumber: cmdNumber): TCommand;
-
- VAR
- aColumnFormatter: TColumnFormatter;
-
- BEGIN { TCalcDocument.DoMenuCommand }
- DoMenuCommand := NIL;
- CASE aCmdNumber OF
- cRecalculate:
- DoRecalculate(kForceAutomatic, kSetDependents);
- cAutoCalc:
- BEGIN
- fCalcMode := Automatic;
- DoRecalculate(kForceAutomatic, kSetDependents);
- END;
- cManualCalc:
- fCalcMode := Manual;
-
- cGeneral, cNoDecimal, cDecimal, cScientific, cSystemJustify, cForceLeftJustify, cRightJustify, cCenter:
- BEGIN
- NEW(aColumnFormatter);
- FailNIL(aColumnFormatter);
- aColumnFormatter.IFormatter(SELF, aCmdNumber);
- DoMenuCommand := aColumnFormatter;
- END;
-
- OTHERWISE
- DoMenuCommand := INHERITED DoMenuCommand(aCmdNumber);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AWriteFile}
-
- PROCEDURE TCalcDocument.DoNeedDiskSpace(VAR dataForkBytes, rsrcForkBytes: LONGINT);
-
- VAR
- r: Rect;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE AccountForCell(aCell: GridCell);
-
- BEGIN
- dataForkBytes := dataForkBytes + GetCell(aCell.v, aCell.h).GetDiskSize(FALSE);
- END;
-
- BEGIN
- { get Print record requirements }
- INHERITED DoNeedDiskSpace(dataForkBytes, rsrcForkBytes);
-
- dataForkBytes := dataForkBytes + SIZEOF(CalcDocDiskInfo) + SIZEOF(RowDiskInfo) *
- fAllocatedRows + SIZEOF(ColumnDiskInfo) * fAllocatedColumns;
- r := fInUseBounds;
- EachExistingCellDo(r, AccountForCell);
-
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AReadFile}
-
- PROCEDURE TCalcDocument.DoRead(aRefNum: INTEGER;
- rsrcExists, forPrinting: BOOLEAN);
-
- VAR
- i: INTEGER;
- noOfCells: INTEGER;
- noOfRows: INTEGER;
- noOfColumns: INTEGER;
- r: RowNumber;
- c: ColumnNumber;
- aCell: TCell;
- aRow: TRow;
- aColumn: TColumn;
- fi: FailInfo;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE ReadDocInfo;
-
- VAR
- theDocInfo: CalcDocDiskInfo;
-
- BEGIN
- ReadBytes(aRefNum, SIZEOF(theDocInfo), @theDocInfo);
-
- WITH theDocInfo DO
- BEGIN
- fDimensions := dimensions;
- fCalcMode := calcMode;
- noOfRows := allocatedRows;
- noOfColumns := allocatedColumns;
- fAllocatedCells := allocatedCells;
- fSelectionType := NoSelection;
- fEditRow := editRow;
- fEditColumn := editColumn;
- END;
-
- WITH fDimensions DO
- BEGIN
- fNoOfRows := bottom - top + 1;
- fNoOfColumns := right - left + 1;
- END;
-
- { Save the number of cells to be read, then set fAllocatedCells to
- zero. As each cell is read fAllocatedCells is incremented.
- When we've finished, noOfCells must equal fAllocatedCells. }
- noOfCells := fAllocatedCells;
- DoInitialState; { clear allocation counts }
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE HdlReadFailure(error: OSErr;
- message: LONGINT);
-
- BEGIN
- { Oh Boy are we in trouble }
- { Need to set back rows and columns to reflect the number read in so
- the freedata routine (which will eventually be called by other
- failure handlers on the stack) won't try to free unallocated objects}
- IF c = 0 THEN
- BEGIN
- { We died while reading the rows in}
- fNoOfRows := r - 1;
- fNoOfColumns := 0;
- END
- ELSE IF i = 0 THEN
- BEGIN
- { Died in the columns }
- fNoOfColumns := c - 1;
- END;
- END;
-
- BEGIN { DoRead }
- CatchFailures(fi, HdlReadFailure);
- INHERITED DoRead(aRefNum, rsrcExists, forPrinting);
-
- ReadDocInfo; { Get info about the document }
- r := 0; c := 0; i := 0; { Initialized so failure handler knows where
- we died }
-
- FOR i := 1 TO noOfRows DO { Get info about each row }
- BEGIN
- ReadBytes(aRefNum, SIZEOF(r), @r);
- aRow := GetRow(r);
- aRow.ReadFromDisk(aRefNum);
- END;
-
- FOR i := 1 TO noOfColumns DO { Get info about each column }
- BEGIN
- ReadBytes(aRefNum, SIZEOF(c), @c);
- aColumn := GetColumn(c);
- aColumn.ReadFromDisk(aRefNum);
- END;
-
- FOR i := 1 TO noOfCells DO { Read in the cells }
- BEGIN
- ReadCellCoordinate(aRefNum, r, c);
- aCell := GetCell(r, c);
- aCell.ReadFromDisk(aRefNum);
- END;
-
- {$IFC qDebug}
- IF gIntenseDebugging THEN
- BEGIN
- WRITELN('TCalcDocument.DoRead: noOfCells=', noOfCells);
- IF noOfCells <> fAllocatedCells THEN
- BEGIN
- WRITELN('TCalcDocument.DoRead: Wrong number of cells. noOfCells=', noOfCells,
- ', fAllocatedCells=', fAllocatedCells);
- ProgramBreak('');
- END;
- END;
- {$ENDC}
-
- Success(fi);
- END; { DoRead }
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCalcDocument.DoRecalculate(forceAutomatic: BOOLEAN;
- setDependents: BOOLEAN);
-
- VAR
- r: Rect;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE RecalcCell(aCell: GridCell);
-
- BEGIN
- GetCell(aCell.v, aCell.h).Recalculate(forceAutomatic, setDependents);
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE RecalcExistingCell(aCell: GridCell);
-
- VAR
- theCell: TCell;
-
- BEGIN
- theCell := GetExistingCell(aCell.v, aCell.h);
- IF theCell <> NIL THEN
- theCell.Recalculate(forceAutomatic, setDependents);
- END;
-
- BEGIN
- IF IsAutoCalc | forceAutomatic THEN
- BEGIN
- r := fInUseBounds;
- EachExistingCellDo(r, RecalcCell);
- END
- ELSE
- fCellsView.EachSelectedCellDo(RecalcExistingCell);
- SetChangeCount(Max(fChangeCount + 1, 1)); { enable Save - document may have changed }
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCalcDocument.DoSetupMenus; OVERRIDE;
-
- VAR
- justification: INTEGER;
- Style: TypeOfStyle;
- columnFormat: FormatRecord;
-
- BEGIN
-
- INHERITED DoSetupMenus;
-
- Enable(cRecalculate, TRUE);
- EnableCheck(cAutoCalc, TRUE, IsAutoCalc);
- EnableCheck(cManualCalc, TRUE, fCalcMode = Manual);
-
- IF fColumnIsSelected THEN
- BEGIN
- IF ColumnExists(fEditColumn) THEN
- columnFormat := GetColumn(fEditColumn).fFormat
- ELSE
- columnFormat := gDefaultFormat;
- justification := columnFormat.fJustification;
- Style := columnFormat.fStyle;
-
- EnableCheck(cSystemJustify, TRUE, justification = teJustSystem);
- EnableCheck(cForceLeftJustify, TRUE, justification = teForceLeft);
- EnableCheck(cRightJustify, TRUE, justification = TEJustRight);
- EnableCheck(cCenter, TRUE, justification = TEJustCenter);
-
- EnableCheck(cGeneral, TRUE, Style = General);
- EnableCheck(cDecimal, TRUE, Style = DecimalStyle);
- EnableCheck(cNoDecimal, TRUE, Style = NoDecimal);
- EnableCheck(cScientific, TRUE, Style = Scientific);
- END
- ELSE
- BEGIN
- Enable(cSystemJustify, FALSE);
- Enable(cForceLeftJustify, FALSE);
- Enable(cRightJustify, FALSE);
- Enable(cCenter, FALSE);
-
- Enable(cGeneral, FALSE);
- Enable(cDecimal, FALSE);
- Enable(cNoDecimal, FALSE);
- Enable(cScientific, FALSE);
- END;
-
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AWriteFile}
-
- PROCEDURE TCalcDocument.DoWrite(aRefNum: INTEGER;
- makingCopy: BOOLEAN);
-
- VAR
- cellsWritten: INTEGER;
- r: Rect;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE WriteDocInfo;
-
- VAR
- theDocInfo: CalcDocDiskInfo;
-
- BEGIN
- WITH theDocInfo DO
- BEGIN
- dimensions := fDimensions;
- calcMode := fCalcMode;
- allocatedRows := fAllocatedRows;
- allocatedColumns := fAllocatedColumns;
- allocatedCells := fAllocatedCells;
- selectionType := NoSelection;
- editRow := fEditRow;
- editColumn := fEditColumn;
- END;
- WriteBytes(aRefNum, SIZEOF(theDocInfo), @theDocInfo);
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE WriteRow(aCell: GridCell);
-
- BEGIN
- GetRow(aCell.v).WriteToDisk(aRefNum);
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE WriteColumn(aCell: GridCell);
-
- VAR
- theColumn: TColumn;
-
- BEGIN
- theColumn := GetColumn(aCell.h);
- theColumn.fWidth := fColumnsView.GetColWidth(aCell.h);
- theColumn.WriteToDisk(aRefNum);
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE WriteCell(aCell: GridCell);
-
- BEGIN
- GetCell(aCell.v, aCell.h).WriteToDisk(aRefNum);
- cellsWritten := cellsWritten + 1;
- END;
-
- BEGIN
- INHERITED DoWrite(aRefNum, makingCopy);
-
- WriteDocInfo; { Write info about the document }
-
- EachExistingRowDo(WriteRow); { Write info about each row }
- EachExistingColumnDo(WriteColumn); { Write info about each column }
-
- cellsWritten := 0;
- r := fInUseBounds;
- EachExistingCellDo(r, WriteCell); { Write out the cells }
-
- {$IFC qDebug}
- IF cellsWritten <> fAllocatedCells THEN
- ProgramBreak('DoWrite: Incorrect number of cells written');
- {$ENDC}
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCalcDocument.EachExistingRowDo(PROCEDURE
- DoToCell(aCell: GridCell));
- { Perform DoToCell for each ALLOCATED Row }
-
- VAR
- r: RowNumber;
- aCell: GridCell;
- aRect: Rect;
-
- BEGIN
- aRect := fInUseBounds;
- WITH aRect DO
- BEGIN
- FOR r := top TO bottom DO
- BEGIN
- IF RowExists(r) THEN
- BEGIN
- aCell.h := 1;
- aCell.v := r;
- DoToCell(aCell);
- END;
- END;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCalcDocument.EachExistingColumnDo(PROCEDURE
- DoToCell(aCell: GridCell));
- { Perform DoToCell for each ALLOCATED Column }
-
- VAR
- c: ColumnNumber;
- aCell: GridCell;
- aRect: Rect;
-
- BEGIN
- aRect := fInUseBounds;
- WITH aRect DO
- BEGIN
- FOR c := left TO right DO
- BEGIN
- IF ColumnExists(c) THEN
- BEGIN
- aCell.h := c;
- aCell.v := 1;
- DoToCell(aCell);
- END;
- END;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCalcDocument.EachExistingCellDo(cellRange: Rect;
- PROCEDURE
- DoToCell(aCell: GridCell));
- { Perform DoToCell for each ALLOCATED cell within a range of cells. }
-
- VAR
- r: RowNumber;
- c: ColumnNumber;
- aCell: GridCell;
-
- BEGIN
- ConstrainToUsedCells(cellRange);
- WITH cellRange DO
- BEGIN
- FOR r := top TO bottom DO
- BEGIN
- FOR c := left TO right DO
- BEGIN
- IF CellExists(r, c) THEN
- BEGIN
- aCell.h := c;
- aCell.v := r;
- DoToCell(aCell);
- END;
- END;
- END;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCalcDocument.EditCell;
- { Change the formula of the cell being edited to the string in the entry view }
-
- VAR
- theString: Str255;
-
- BEGIN
- fEntryView.GetAsString(theString);
- IF fEditCell = NIL THEN
- fEditCell := GetCell(fEditRow, fEditColumn);
- fEditCell.SetToString(theString);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AFields}
-
- PROCEDURE TCalcDocument.Fields(PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- VAR
- aString: Str255;
-
- BEGIN
- DoToField('TCalcDocument', NIL, bClass);
- DoToField('fEditCell', @fEditCell, bObject);
- DoToField('fNoOfRows', @fNoOfRows, bInteger);
- DoToField('fNoOfColumns', @fNoOfColumns, bInteger);
- DoToField('fColumns', @fColumns, bObject);
- DoToField('fRows', @fRows, bObject);
- DoToField('fRowOffset', @fRowOffset, bInteger);
- DoToField('fColumnOffset', @fColumnOffset, bInteger);
- DoToField('fCellsView', @fCellsView, bObject);
- DoToField('fRowsView', @fRowsView, bObject);
- DoToField('fColumnsView', @fColumnsView, bObject);
- DoToField('fEntryView', @fEntryView, bObject);
- DoToField('fCoordView', @fCoordView, bObject);
- DoToField('fDimensions', @fDimensions, bRect);
- DoToField('fInUseBounds', @fInUseBounds, bRect);
- IF IsAutoCalc THEN
- aString := 'Automatic'
- ELSE
- aString := 'Manual';
- DoToField('fCalcMode', @aString, bString);
- DoToField('fAllocatedRows', @fAllocatedRows, bInteger);
- DoToField('fAllocatedColumns', @fAllocatedColumns, bInteger);
- DoToField('fAllocatedCells', @fAllocatedCells, bInteger);
- CASE fSelectionType OF
- NoSelection:
- aString := 'NoSelection';
- CellSelection:
- aString := 'CellSelection';
- RowSelection:
- aString := 'RowSelection';
- ColumnSelection:
- aString := 'ColumnSelection';
- AllSelection:
- aString := 'AllSelection';
- END;
- DoToField('fSelectionType', @aString, bString);
- DoToField('fEditRow', @fEditRow, bByte);
- DoToField('fEditColumn', @fEditColumn, bByte);
- INHERITED Fields(DoToField);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCalcDocument.FreeCell(theCell: TCell);
-
- PROCEDURE RemoveReferences(theObject: TObject);
- { remove any reference to cell that is about to be freed }
- VAR
- theCName: MAName;
-
- BEGIN
- IF IsObject(theObject) & Member(theObject, TCell) THEN { may have been freed }
- BEGIN
- TCell(theObject).fReferences.Delete(theCell);
- END;
- END;
-
- BEGIN
- {$IFC qDebug}
- IF fCells[theCell.fRow, theCell.fColumn] <> theCell THEN
- ProgramBreak('TCalcDocument.FreeCell: Cell table inconsistent');
- {$ENDC}
-
- fCells[theCell.fRow, theCell.fColumn] := NIL;
- IF theCell.fDependents <> NIL THEN
- theCell.fDependents.Each(RemoveReferences);
-
- FreeIfObject(theCell);
- theCell := NIL;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCalcDocument.FreeData;
-
- VAR
- r: RowNumber;
- c: ColumnNumber;
- oldState: BOOLEAN;
-
- BEGIN
- oldState := Lock(TRUE); { HLock(Handle(SELF)) }
- WITH fInUseBounds DO
- FOR r := top TO bottom DO
- FOR c := left TO right DO
- IF fCells[r, c] <> NIL THEN
- {$Push} {$H-}
- FreeCell(fCells[r, c]);
- {$Pop}
-
- FOR r := 1 TO fNoOfRows DO
- BEGIN
- FreeIfObject(fRows[r]); { This is paranoia setting in}
- fRows[r] := NIL;
- END;
-
- FOR c := 1 TO fNoOfColumns DO
- BEGIN
- FreeIfObject(fColumns[c]); { I admit it - I'm paranoid}
- fColumns[c] := NIL;
- END;
-
- IF Lock(oldState) THEN;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCalcDocument.FreeDeletedCells;
- { Free each deleted cell. }
-
- VAR
- r: RowNumber;
- c: ColumnNumber;
- theCell: TCell;
- cellRange: Rect;
-
- BEGIN
- cellRange := fInUseBounds;
- WITH cellRange DO
- FOR r := top TO bottom DO
- FOR c := left TO right DO
- BEGIN
- theCell := fCells[r, c];
- IF (theCell <> NIL) & theCell.fDeleted THEN
- FreeCell(theCell);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- FUNCTION TCalcDocument.GetCell(r: RowNumber;
- c: ColumnNumber): TCell;
- { Return the cell object for the given coordinates. If a cell object
- doesn't already exist, create one. }
-
- VAR
- theCell: TCell;
-
- BEGIN
- IF CellExists(r, c) THEN
- theCell := fCells[r, c]
- ELSE
- BEGIN
- NEW(theCell);
- FailNIL(theCell);
- theCell.ICell(SELF, r, c);
- AddCell(theCell, r, c);
- END;
-
- GetCell := theCell;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- FUNCTION TCalcDocument.GetColumn(c: ColumnNumber): TColumn;
-
- VAR
- theColumn: TColumn;
-
- BEGIN
- IF ColumnExists(c) THEN
- theColumn := fColumns[c]
- ELSE
- BEGIN
- NEW(theColumn);
- FailNIL(theColumn);
- theColumn.IColumn(c);
- AddColumn(theColumn);
- END;
-
- GetColumn := theColumn;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- FUNCTION TCalcDocument.GetExistingCell(r: RowNumber;
- c: ColumnNumber): TCell;
- { Like GetCell, only return NIL if the cell object doesn't exist }
-
- BEGIN
- IF CellExists(r, c) THEN
- GetExistingCell := fCells[r, c]
- ELSE
- GetExistingCell := NIL;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- FUNCTION TCalcDocument.IsAutoCalc: BOOLEAN;
-
- BEGIN
- IsAutoCalc := fCalcMode = Automatic;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- FUNCTION TCalcDocument.GetRow(r: RowNumber): TRow;
-
- VAR
- theRow: TRow;
-
- BEGIN
- IF RowExists(r) THEN
- theRow := fRows[r]
- ELSE
- BEGIN
- NEW(theRow);
- FailNIL(theRow);
- theRow.IRow(r);
- AddRow(theRow);
- END;
-
- GetRow := theRow;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- FUNCTION TCalcDocument.RowExists(r: RowNumber): BOOLEAN;
-
- BEGIN
- RowExists := (r > 0) & (r <= kMaxRows) & (fRows[r] <> NIL);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCalcDocument.SetEntry(r: RowNumber;
- c: ColumnNumber);
- { Set the string in TEntryView to the formula in the cell }
-
- VAR
- theString: Str255;
-
- BEGIN
- IF CellExists(r, c) THEN
- BEGIN
- fCells[r, c].GetAsString(theString);
- fEntryView.SetToString(theString);
- END
- ELSE
- fEntryView.SetToString('');
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCalcDocument.UndeleteCell(r: RowNumber;
- c: ColumnNumber);
-
- BEGIN
- IF fCells[r, c] <> NIL THEN { can't use CellExists b/c it screens
- deleted cells }
- BEGIN
- fCells[r, c].SetDeleteState(FALSE);
- fAllocatedCells := fAllocatedCells + 1;
- END;
- END;
-
- {***************************************************************************************************
- T C a l c W i n d o w
- ***************************************************************************************************}
- {$S AOpen}
-
- PROCEDURE TCalcWindow.IRes(itsDocument: TDocument;
- itsSuperView: TView;
- VAR itsParams: Ptr); OVERRIDE;
-
- VAR
- minSize: Point;
-
- BEGIN
- INHERITED IRes(itsDocument, itsSuperView, itsParams);
- minSize.h := 284;
- minSize.v := 126;
- SetResizeLimits(minSize, gStdWSizeRect.botRight);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCalcWindow.Draw(area: Rect); OVERRIDE;
-
- BEGIN
- { draw the extra borders for the rows and columns views }
- PenNormal;
-
- { rows }
- MoveTo(0, 35);
- Line(kRowTitleWidth - 1, 0);
-
- MoveTo(0, 35 + kCellHeight - 1);
- Line(kRowTitleWidth - 1, 0);
-
- { columns }
- MoveTo(kRowTitleWidth - 1, 35);
- Line(0, kCellHeight - 1);
-
- INHERITED Draw(area);
- END;
-
- {***************************************************************************************************
- T C e l l s V i e w
- ***************************************************************************************************}
- {$S AOpen}
-
- PROCEDURE TCellsView.ICellsView(itsDocument: TCalcDocument;
- forClipboard: BOOLEAN;
- itsParent: TView);
-
- BEGIN
- fCalcDocument := itsDocument;
- fLastOptionKey := FALSE; { Used for DoSetCursor to the grabber hand }
-
- ITextGridView(itsDocument, itsParent, gZeroVPt, gZeroVPt, sizeVariable, sizeVariable,
- itsDocument.fNoOfRows, itsDocument.fNoOfColumns, 0, kCellWidth, kAdorn, kAdorn,
- 0, 0, FALSE, gSystemStyle);
- fIdleFreq := Max(GetCaretTime DIV 2, 1); { So we can trackCursor for the GrabberHand.
- With MF 7.0 we could setup a VBL that
- monitered the modifiers and called Wakeup
- with our PID. Even better would be a call
- that set the event manager so that an
- event could be returned on modifier key
- changes… oh, well. }
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AOpen}
-
- PROCEDURE TCellsView.IRes(itsDocument: TDocument;
- itsSuperView: TView;
- VAR itsParams: Ptr); OVERRIDE;
-
- BEGIN
- fCalcDocument := TCalcDocument(itsDocument);
- INHERITED IRes(itsDocument, itsSuperView, itsParams);
- fIdleFreq := Max(GetCaretTime DIV 2, 1); { So we can trackCursor for the GrabberHand.
- With MF 7.0 we could setup a VBL that
- monitered the modifiers and called Wakeup
- with our PID. Even better would be a call
- that set the event manager so that an
- event could be returned on modifier key
- changes… oh, well. }
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCellsView.AdornRow(aRow: INTEGER;
- area: Rect); OVERRIDE;
-
- BEGIN
- PenPat(gRowSeparatorPattern);
- PenSize(1, 1);
-
- MoveTo(area.left, area.bottom - 1);
- LineTo(area.right - 1, area.bottom - 1);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCellsView.AdornCol(aCol: INTEGER;
- area: Rect); OVERRIDE;
-
- BEGIN
- PenPat(gColumnSeparatorPattern);
- PenSize(1, 1);
-
- MoveTo(area.right - 1, area.top);
- LineTo(area.right - 1, area.bottom - 1);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AClipBoard}
-
- FUNCTION TCellsView.ContainsClipType(aType: ResType): BOOLEAN;
-
- BEGIN
- ContainsClipType := aType = kCalcScrapType;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- FUNCTION TCellsView.DoIdle(phase: IdlePhase): BOOLEAN;
-
- CONST
- kOptionKey = $3A;
-
- VAR
- aKeyMap: KeyMap;
-
- BEGIN
- DoIdle := FALSE; { Didn't free myself }
-
- GetKeys(aKeyMap);
- IF fLastOptionKey <> aKeyMap[kOptionKey] THEN
- BEGIN
- fLastOptionKey := aKeyMap[kOptionKey];
- gApplication.InvalidateCursorRgn; { Since we track the option key, we now need
- to recalculate cursor rgn and SET the
- cursor at next opportunity }
- END;
-
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- FUNCTION TCellsView.DoKeyCommand(Ch: CHAR;
- aKeyCode: INTEGER;
- VAR info: EventInfo): TCommand;
- { This view only handles arrow keys, tab, return and enter. It assumes
- the other keys are handled by the entry view object. }
-
- VAR
- r: RowNumber;
- c: ColumnNumber;
- aCell: GridCell;
- minToSee: Point;
- aRect: VRect;
-
- BEGIN
- DoKeyCommand := NIL;
-
- c := fCalcDocument.fEditColumn;
- r := fCalcDocument.fEditRow;
-
- CASE Ch OF
- chEnter:
- BEGIN
- { Stay on same cell }
- END;
- chTab, chRight:
- c := Min(c + 1, fCalcDocument.fNoOfColumns);
- chLeft:
- c := Max(c - 1, 1);
- chUp:
- r := Max(r - 1, 1);
- chReturn, chDown:
- r := Min(r + 1, fCalcDocument.fNoOfRows);
- OTHERWISE
- BEGIN
- DoKeyCommand := INHERITED DoKeyCommand(Ch, aKeyCode, info);
- fCalcDocument.fEditCell := fCalcDocument.GetCell(r, c);
- EXIT(DoKeyCommand);
- END;
- END;
-
- aCell.h := c;
- aCell.v := r;
-
- WITH fCalcDocument DO
- BEGIN
- SetChangeCount(Max(fChangeCount + 1, 1)); { enable Save - document may have changed }
-
- fEntryView.EditMode(FALSE);
- fColumnsView.SetEmptySelection(kHighlight);
- fRowsView.SetEmptySelection(kHighlight);
- fColumnIsSelected := FALSE;
-
- SelectCell(aCell, kDontExtend, kHighlight, kSelect);
- IF fEntryView.fTouched THEN
- DoRecalculate(NOT kForceAutomatic, kSetDependents);
- ScrollSelectionIntoView(TRUE);
-
- { fix the columns view }
- minToSee.h := fColumnsView.GetColWidth(aCell.h);
- minToSee.v := kCellHeight;
- aCell.v := 1;
- fColumnsView.CellToVRect(aCell, aRect);
- fColumnsView.RevealRect(aRect, minToSee, TRUE);
-
- { fix the rows view }
- minToSee.h := kCellWidth;
- minToSee.v := kCellHeight;
- aCell.v := r;
- aCell.h := 1;
- fRowsView.CellToVRect(aCell, aRect);
- fRowsView.RevealRect(aRect, minToSee, TRUE);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ASelCommand}
-
- FUNCTION TCellsView.DoMenuCommand(aCmdNumber: cmdNumber): TCommand; OVERRIDE;
-
- VAR
- aCellEditCommand: TCellEditCommand;
- aCellPasteCommand: TCellPasteCommand;
- cellsToSelect: RgnHandle;
- aRect: Rect;
-
- BEGIN
- CASE aCmdNumber OF
- cSelectAll:
- BEGIN
- aRect := fCalcDocument.fInUseBounds;
- WITH aRect DO
- BEGIN
- right := right + 1;
- bottom := bottom + 1;
- END;
- cellsToSelect := MakeNewRgn;
- RectRgn(cellsToSelect, aRect);
- SetSelection(cellsToSelect, kDontExtend, kHighlight, kSelect);
- DisposeRgn(cellsToSelect);
- WITH fCalcDocument DO
- BEGIN
- fSelectionType := AllSelection;
- fRowsView.SetEmptySelection(kHighlight);
- fColumnsView.SetEmptySelection(kHighlight);
- fColumnIsSelected := FALSE;
- END;
- DoMenuCommand := NIL;
- END;
-
- cCut, cCopy, cClear:
- { If user isn't editing this cell, he must want the cell itself. }
- IF NOT fCalcDocument.fEntryView.fTEditing THEN
- BEGIN
- NEW(aCellEditCommand);
- FailNIL(aCellEditCommand);
- aCellEditCommand.ICellEditCommand(fCalcDocument, aCmdNumber);
- DoMenuCommand := aCellEditCommand;
- END
- ELSE
- BEGIN { get ready for TextEdit operation }
- WITH fCalcDocument DO
- fEditCell := GetCell(fEditRow, fEditColumn);
- DoMenuCommand := INHERITED DoMenuCommand(aCmdNumber);
- END;
-
- cPaste:
- IF gClipView.ContainsClipType(kCalcScrapType) THEN
- BEGIN
- NEW(aCellPasteCommand);
- FailNIL(aCellPasteCommand);
- aCellPasteCommand.ICellPasteCommand(fCalcDocument);
- DoMenuCommand := aCellPasteCommand;
- END
- ELSE
- BEGIN { paste text into entry view }
- WITH fCalcDocument DO
- BEGIN
- fEditCell := GetCell(fEditRow, fEditColumn);
- IF NOT fEntryView.fTEditing THEN
- fEntryView.SetEditMode; { prepare view for paste of text }
- END;
- DoMenuCommand := INHERITED DoMenuCommand(aCmdNumber);
- END;
-
- OTHERWISE
- DoMenuCommand := INHERITED DoMenuCommand(aCmdNumber);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ASelCommand}
-
- FUNCTION TCellsView.DoMouseCommand(VAR theMouse: Point;
- VAR info: EventInfo;
- VAR hysteresis: Point): TCommand; OVERRIDE;
-
- VAR
- aCellSelector: TCalcSelectCommand;
- aColumnSizer: TColumnSizer;
- aCell: GridCell;
- whichPart: GridViewPart;
- aRow: INTEGER;
- aCol: INTEGER;
- aGrabber: TGrabberTracker;
-
- BEGIN
- DoMouseCommand := NIL;
- whichPart := IdentifyPoint(theMouse, aRow, aCol);
- aCell.h := aCol;
- aCell.v := aRow;
-
- IF info.theOptionKey THEN
- BEGIN
- NEW(aGrabber);
- FailNIL(aGrabber);
- aGrabber.IGrabberTracker(cNoCommand, fCalcDocument, SELF, GetScroller(FALSE));
- DoMouseCommand := aGrabber;
- END
- ELSE
- BEGIN
- CASE whichPart OF
- inCell:
- BEGIN
- NEW(aCellSelector);
- FailNIL(aCellSelector);
- aCellSelector.ICalcSelectCommand(fCalcDocument, SELF, info.theShiftKey,
- info.theCmdKey);
- DoMouseCommand := aCellSelector;
- fCalcDocument.fSelectionType := CellSelection;
- END;
-
- inColumn, inVertex:
- BEGIN
- IF aCol > 1 THEN
- BEGIN
- NEW(aColumnSizer);
- FailNIL(aColumnSizer);
- aColumnSizer.IColumnSizer(fCalcDocument, aCol - 1);
- DoMouseCommand := aColumnSizer;
- END;
- END;
-
- OTHERWISE;
- END;
- fCalcDocument.fColumnsView.SetEmptySelection(kHighlight);
- fCalcDocument.fRowsView.SetEmptySelection(kHighlight);
- fCalcDocument.fColumnIsSelected := FALSE;
- fCalcDocument.fEditCell := NIL;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- FUNCTION TCellsView.DoSetCursor(localPoint: Point;
- cursorRgn: RgnHandle): BOOLEAN; OVERRIDE;
-
- CONST
- kOptionKey = $3A;
-
- VAR
- aRow: INTEGER;
- aCol: INTEGER;
- aKeyMap: KeyMap;
- cellsExtent: VRect;
- cellsQDExtent, columnQDExtent: Rect;
-
- BEGIN
- DoSetCursor := FALSE;
-
- GetKeys(aKeyMap);
-
- { We may have been called from a mouse-moved. Be kind to the DoIdle }
- fLastOptionKey := aKeyMap[kOptionKey];
-
- IF fLastOptionKey THEN
- BEGIN
- DoSetCursor := TRUE;
- SetCursor(GetCursor(kGrabberHand)^^);
- GetQDExtent(cellsQDExtent);
- RectRgn(cursorRgn, cellsQDExtent);
- END
- ELSE
- CASE IdentifyPoint(localPoint, aRow, aCol) OF
- badChoice: ;
- inColumn, inVertex:
- IF aCol > 1 THEN
- BEGIN
- DoSetCursor := TRUE;
- SetCursor(GetCursor(kColumnSizingCursor)^^);
- ColToVRect(Min(aCol, fNumOfCols), 1, cellsExtent);
- ViewToQDRect(cellsExtent, cellsQDExtent);
- columnQDExtent := cellsQDExtent;
-
- { Which edge is the mouse closer to? }
- IF abs(columnQDExtent.right - localPoint.h) < abs(columnQDExtent.left -
- localPoint.h) THEN
- columnQDExtent.left := columnQDExtent.right;
-
- columnQDExtent.left := columnQDExtent.left - fColInset DIV 2;
- columnQDExtent.right := columnQDExtent.left + fColInset;
- RectRgn(cursorRgn, columnQDExtent);
- END;
- inRow, inCell:
- BEGIN
- DoSetCursor := TRUE;
- SetCursor(GetCursor(plusCursor)^^);
- ColToVRect(Min(aCol, fNumOfCols), 1, cellsExtent);
- InsetVRect(cellsExtent, fColInset DIV 2, 0); { Account for the column resizer }
- ViewToQDRect(cellsExtent, cellsQDExtent);
- RectRgn(cursorRgn, cellsQDExtent);
- END;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCellsView.DoSetupMenus; OVERRIDE;
-
- VAR
- selection: TypeOfSelection;
-
- BEGIN
- INHERITED DoSetupMenus;
-
- { If user isn't editing, then assume edit commands refer to cells }
- IF NOT fCalcDocument.fEntryView.fTEditing THEN
- BEGIN
- SetEditCmdName(cCut, cCutCells);
- SetEditCmdName(cCopy, cCopyCells);
- SetEditCmdName(cClear, cClearCells);
-
- CanPaste(kCalcScrapType);
- END;
-
- selection := fCalcDocument.fSelectionType;
- Enable(cCut, selection <> NoSelection);
- Enable(cCopy, selection <> NoSelection);
- Enable(cClear, selection <> NoSelection);
- Enable(cSelectAll, TRUE);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCellsView.DrawCell(aCell: GridCell;
- aQDRect: Rect); OVERRIDE;
-
- VAR
- theCell: TCell;
- theString: Str255;
-
- BEGIN
- theCell := fCalcDocument.GetExistingCell(aCell.v, aCell.h);
- IF (theCell <> NIL) THEN
- WITH theCell DO
- BEGIN
- GetValueAsString(theString);
- SmartDrawString(theString, aQDRect,
- fCalcDocument.GetColumn(aCell.h).fFormat.fJustification);
- END;
-
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AFields}
-
- PROCEDURE TCellsView.Fields(PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- BEGIN
- DoToField('TCellsView', NIL, bClass);
- DoToField('fCalcDocument', @fCalcDocument, bObject);
- INHERITED Fields(DoToField);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellsView.GetVisibleCells(VAR visibleCells: Rect);
-
- VAR
- visibleRect: Rect;
- visibleVRect: VRect;
- topLeftVPoint: VPoint;
-
- BEGIN
- IF Focus THEN; { appease QDToViewRect }
- GetVisibleRect(visibleRect);
- topLeftVPoint := GetScroller(TRUE).fTranslation;
- visibleRect.topLeft := ViewToQDPt(topLeftVPoint);
- QDToViewRect(visibleRect, visibleVRect);
- visibleCells.topLeft := VPointToCell(visibleVRect.topLeft);
- visibleCells.botRight := VPointToCell(visibleVRect.botRight);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- FUNCTION TCellsView.IsCellVisible(aCell: GridCell): BOOLEAN;
-
- VAR
- visibleCells: Rect;
-
- BEGIN
- GetVisibleCells(visibleCells);
- IsCellVisible := PtInRect(aCell, visibleCells); { ??? use fCalcDocument.CellInRange }
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellsView.PositionAtCell(aCell: GridCell);
-
- VAR
- aRect: VRect;
- minToSee: Point;
- r: INTEGER;
-
- BEGIN
- { position the cells view first }
- CellToVRect(aCell, aRect);
- WITH aRect DO
- SetPt(minToSee, right - left, bottom - top);
- RevealRect(aRect, minToSee, TRUE);
-
- WITH fCalcDocument DO
- BEGIN
- { fix up the columns view }
- r := aCell.v;
- minToSee.h := fColumnsView.GetColWidth(aCell.h);
- minToSee.v := kCellHeight;
- aCell.v := 1;
- fColumnsView.CellToVRect(aCell, aRect);
- fColumnsView.RevealRect(aRect, minToSee, TRUE);
-
- { fix up the rows view }
- minToSee.h := kCellWidth;
- minToSee.v := kCellHeight;
- aCell.v := r;
- aCell.h := 1;
- fRowsView.CellToVRect(aCell, aRect);
- fRowsView.RevealRect(aRect, minToSee, TRUE);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellsView.ReSelect(cellRegion: RgnHandle);
-
- VAR
- aCell: GridCell;
-
- BEGIN
- aCell := cellRegion^^.rgnBBox.topLeft;
- IF NOT IsCellVisible(aCell) THEN
- PositionAtCell(aCell); { position cellRegion at top left of grid }
-
- IF NOT EqualRect(cellRegion^^.rgnBBox, fSelections^^.rgnBBox) THEN
- BEGIN
- WITH fCalcDocument DO
- BEGIN
- fColumnsView.SetEmptySelection(kHighlight);
- fRowsView.SetEmptySelection(kHighlight);
- fColumnIsSelected := FALSE;
- END;
- SetSelection(cellRegion, kDontExtend, kHighlight, kSelect);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellsView.ReSelectCell(aCell: GridCell);
-
- VAR
- cellRect: Rect;
-
- BEGIN
- IF NOT IsCellVisible(aCell) THEN
- PositionAtCell(aCell); { position aCell at top left of grid }
-
- WITH aCell DO
- SetRect(cellRect, h, v, h + 1, v + 1);
- IF NOT EqualRect(cellRect, fSelections^^.rgnBBox) THEN
- BEGIN
- WITH fCalcDocument DO
- BEGIN
- fColumnsView.SetEmptySelection(kHighlight);
- fRowsView.SetEmptySelection(kHighlight);
- fColumnIsSelected := FALSE;
- END;
- SelectCell(aCell, kDontExtend, kHighlight, kSelect);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellsView.ScrollSelectionIntoView(redraw: BOOLEAN); OVERRIDE;
-
- VAR
- topLeftRect: VRect;
- minToSee: Point;
-
- BEGIN
- IF NOT (EmptyRgn(fSelections)) THEN
- BEGIN
- CellToVRect(fSelections^^.rgnBBox.topLeft, topLeftRect);
- WITH topLeftRect DO
- SetPt(minToSee, right - left, bottom - top);
- RevealRect(topLeftRect, minToSee, redraw);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellsView.SetCell(aCell: GridCell);
-
- BEGIN
- fCalcDocument.EditCell; { cell formula := string in entry view }
- InvalidateCell(aCell); { redraw the cell }
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellsView.SetSelection(cellsToSelect: RgnHandle;
- extendSelection, highlight, select: BOOLEAN); OVERRIDE;
-
- VAR
- aQDRect: Rect;
-
- BEGIN
- WITH fCalcDocument DO
- BEGIN
- INHERITED SetSelection(cellsToSelect, extendSelection, highlight, select);
-
- IF fEntryView.fTouched THEN { "commit" last cell }
- BEGIN
- EditCell; { change fEditCell's formula to the string
- in fEntryView }
- fEntryView.SetToString('');
- END;
-
- IF NOT extendSelection & (cellsToSelect^^.rgnBBox.top <> 0) &
- (cellsToSelect^^.rgnBBox.left <> 0) THEN
- BEGIN
- fEditColumn := cellsToSelect^^.rgnBBox.left;
- fEditRow := cellsToSelect^^.rgnBBox.top;
- fEditCell := fCells[fEditRow, fEditColumn];
-
- IF fCoordView.Focus THEN
- BEGIN
- fCoordView.GetQDExtent(aQDRect);
- fCoordView.InvalidRect(aQDRect);
- END;
- END;
-
- SetEntry(fEditRow, fEditColumn); { set entry view contents to new cell }
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AClipBoard}
-
- PROCEDURE TCellsView.WriteCalcScrap(calcScrap: Handle);
-
- VAR
- scrapOffset: LONGINT;
- scrapInfo: ScrapInfoRecord;
- cellsWritten: INTEGER;
- i: INTEGER;
- r: Rect;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE WriteCellToScrap(aCell: GridCell);
-
- BEGIN
- WITH fCalcDocument.GetCell(aCell.v, aCell.h) DO
- WriteToScrap(calcScrap, scrapOffset);
- cellsWritten := cellsWritten + 1;
- END;
-
- BEGIN
- SetHandleSize(calcScrap, 0);
- scrapOffset := 0;
-
- scrapInfo.selection.top := 1;
- scrapInfo.selection.left := 1;
- scrapInfo.selection.bottom := fCalcDocument.fNoOfRows;
- scrapInfo.selection.right := fCalcDocument.fNoOfColumns;
- scrapInfo.noOfCells := fCalcDocument.fAllocatedCells;
- WriteScrap(calcScrap, scrapOffset, @scrapInfo, SIZEOF(scrapInfo));
-
- cellsWritten := 0;
- WITH fCalcDocument DO
- BEGIN
- FOR i := 1 TO fCalcDocument.fNoOfRows DO
- BEGIN
- WITH fCalcDocument.GetRow(i) DO
- WriteToScrap(calcScrap, scrapOffset);
- END;
-
- FOR i := 1 TO fCalcDocument.fNoOfColumns DO
- BEGIN
- WITH fCalcDocument.GetColumn(i) DO
- WriteToScrap(calcScrap, scrapOffset);
- END;
- r := fCalcDocument.fInUseBounds;
- EachExistingCellDo(r, WriteCellToScrap);
- END;
-
- {$IFC qDebug}
- WRITELN('WriteCalcScrap: Number of cells written: ', cellsWritten: 0);
- IF cellsWritten <> scrapInfo.noOfCells THEN
- BEGIN
- WRITELN('WriteCalcScrap: Incorrect number of cells written.');
- WRITELN(' Should be ', scrapInfo.noOfCells: 0, ', was ', cellsWritten: 0);
- ProgramBreak('');
- END;
- {$ENDC}
-
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AClipBoard}
-
- PROCEDURE TCellsView.WriteTextScrap(textScrap: Handle);
-
- VAR
- r: RowNumber;
- c: ColumnNumber;
- theText: Str255;
- scrapOffset: LONGINT;
- savedPort: GrafPtr;
-
- BEGIN
- GetPort(savedPort); { Use work port because GetValueAsString }
- SetPort(gWorkPort); { …sets the current port's font }
-
- SetHandleSize(textScrap, 0);
- scrapOffset := 0;
-
- FOR r := 1 TO fCalcDocument.fNoOfRows DO
- BEGIN
- FOR c := 1 TO fCalcDocument.fNoOfColumns DO
- BEGIN
- IF fCalcDocument.CellExists(r, c) THEN
- fCalcDocument.GetCell(r, c).GetValueAsString(theText)
- ELSE
- theText := '';
- IF c > 1 THEN
- theText := CONCAT(chTab, theText);
- WriteScrap(textScrap, scrapOffset, POINTER(ORD4(@theText) + 1), LENGTH(theText));
- END;
- theText := chReturn;
- WriteScrap(textScrap, scrapOffset, POINTER(ORD4(@theText) + 1), LENGTH(theText));
- END;
-
- SetPort(savedPort);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AClipBoard}
-
- PROCEDURE TCellsView.WriteToDeskScrap; OVERRIDE;
-
- VAR
- textScrap: Handle;
- calcScrap: Handle;
- err: OSErr;
-
- BEGIN
- textScrap := NewPermHandle(0);
- FailNIL(textScrap);
- WriteTextScrap(textScrap);
- err := PutDeskScrapData(kTextScrapType, textScrap);
- textScrap := DisposeIfHandle(textScrap);
-
- FailOSErr(err);
-
- calcScrap := NewPermHandle(0);
- FailNIL(calcScrap);
- WriteCalcScrap(calcScrap);
- err := PutDeskScrapData(kCalcScrapType, calcScrap);
- calcScrap := DisposeIfHandle(calcScrap);
-
- FailOSErr(err);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ANonRes}
-
- FUNCTION TCellsView.DoBreakFollowing(vhs: VHSelect;
- prevBreak: VCoordinate;
- VAR Automatic: BOOLEAN): VCoordinate; OVERRIDE;
- { Determines where page breaks occur for printing. }
-
- VAR
- thisBreak: VCoordinate;
- rowsPerPage: INTEGER;
- totalWidth: INTEGER;
- width: INTEGER;
- pageWidth: INTEGER;
- extentRect: VRect;
- firstCol: ColumnNumber;
- c: ColumnNumber;
-
- FUNCTION ColumnAtCoord(loc: VCoordinate): INTEGER;
-
- BEGIN
- ColumnAtCoord := 1;
- IF loc = 0 THEN
- EXIT(ColumnAtCoord);
-
- c := 0;
- width := 0;
- REPEAT
- c := c + 1;
- width := width + GetColWidth(c);
- UNTIL width >= loc;
- ColumnAtCoord := c + 1;
- END;
-
- BEGIN
- GetExtent(extentRect);
- CASE vhs OF
- h:
- BEGIN
- rowsPerPage := fPrintHandler.fViewPerPage.v DIV kCellHeight;
- thisBreak := prevBreak + (rowsPerPage * kCellHeight);
- END;
- v:
- BEGIN
- pageWidth := fPrintHandler.fViewPerPage.h;
- totalWidth := 0;
- firstCol := ColumnAtCoord(prevBreak);
- FOR c := firstCol TO fCalcDocument.fNoOfColumns DO
- BEGIN
- width := GetColWidth(c);
- IF totalWidth + width <= pageWidth THEN
- totalWidth := totalWidth + width
- ELSE
- BEGIN
- thisBreak := prevBreak + totalWidth;
- LEAVE;
- END;
- END;
- IF thisBreak = prevBreak THEN { Prevent ∞ loop resizing a far-right column
- (L.T.!) }
- thisBreak := extentRect.right;
- END;
- END;
- thisBreak := Min(thisBreak, extentRect.botRight.vh[gOrthogonal[vhs]]);
-
- {$IFC qDebug}
- IF (thisBreak <= prevBreak) | gDebugPrinting THEN
- BEGIN
- WRITE('TCellsView.DoBreakFollowing: prevBreak=');
- IF vhs = v THEN
- WRITELN('[v]', prevBreak, ', thisBreak=[v]', thisBreak)
- ELSE
- WRITELN('[h]', prevBreak, ', thisBreak=[h]', thisBreak);
-
- IF thisBreak <= prevBreak THEN
- ProgramBreak('thisBreak <= prevBreak');
- END;
- {$ENDC}
-
- DoBreakFollowing := thisBreak;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$IFC qDebug}
- {$S ANonRes}
-
- PROCEDURE TCellsView.DoDrawPageBreak(vhs: VHSelect;
- whichBreak: INTEGER;
- loc: VCoordinate;
- Automatic: BOOLEAN); OVERRIDE;
-
- VAR
- vPt: VPoint;
- qdStartPt: Point;
- qdEndPt: Point;
-
- BEGIN
- IF gDebugPrinting THEN
- BEGIN
- vPt.vh[gOrthogonal[vhs]] := loc;
- vPt.vh[vhs] := 0;
- qdStartPt := ViewToQDPt(vPt);
- vPt.vh[vhs] := fSize.vh[vhs] - gBreaksPenState.pnSize.vh[vhs];
- qdEndPt := ViewToQDPt(vPt);
-
- MoveTo(qdStartPt.h, qdStartPt.v);
- LineTo(qdEndPt.h, qdEndPt.v);
- END;
- END;
- {$ENDC}
-
- {--------------------------------------------------------------------------------------------------}
- {$S ANonRes}
-
- PROCEDURE TCellsView.GetPrintExtent(VAR printExtent: VRect); OVERRIDE;
- { Overridden to provide for Print Selection command. }
-
- VAR
- aRect: VRect;
- tlCell: GridCell;
- brCell: GridCell;
-
- BEGIN
- IF TCalcPrintHandler(fPrintHandler).fCmdNumber = cPrintSelection THEN
- BEGIN
- tlCell := fSelections^^.rgnBBox.topLeft;
- brCell := fSelections^^.rgnBBox.botRight;
- brCell.h := Min(brCell.h - 1, fCalcDocument.fInUseBounds.right);
- brCell.v := Min(brCell.v - 1, fCalcDocument.fInUseBounds.bottom);
- END
- ELSE
- BEGIN
- tlCell := fCalcDocument.fInUseBounds.topLeft;
- brCell := fCalcDocument.fInUseBounds.botRight;
- END;
-
- CellToVRect(tlCell, aRect);
- printExtent.topLeft := aRect.topLeft;
- CellToVRect(brCell, aRect);
- printExtent.botRight := aRect.botRight;
-
- {$IFC qDebug}
- IF gDebugPrinting THEN
- BEGIN
- WrLblVRect('printExtent ', printExtent);
- WRITELN;
- END;
- {$ENDC}
- END;
-
- {***************************************************************************************************
- T R o w s V i e w
- ***************************************************************************************************}
- {$S AOpen}
-
- PROCEDURE TRowsView.IRes(itsDocument: TDocument;
- itsSuperView: TView;
- VAR itsParams: Ptr); OVERRIDE;
-
- BEGIN
- fCalcDocument := TCalcDocument(itsDocument);
- INHERITED IRes(itsDocument, itsSuperView, itsParams);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TRowsView.AdornRow(aRow: INTEGER;
- area: Rect); OVERRIDE;
-
- BEGIN
- PenSize(1, 1);
- PenPat(black);
-
- { right line }
- MoveTo(area.right - 1, area.top);
- LineTo(area.right - 1, area.bottom - 1);
-
- { bottom line }
- MoveTo(area.left, area.bottom - 1);
- LineTo(area.right - 1, area.bottom - 1);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ASelCommand}
-
- FUNCTION TRowsView.DoMouseCommand(VAR theMouse: Point;
- VAR info: EventInfo;
- VAR hysteresis: Point): TCommand; OVERRIDE;
-
- VAR
- aRowSelector: TRowSelector;
-
- BEGIN
- NEW(aRowSelector);
- FailNIL(aRowSelector);
- aRowSelector.IRowSelector(fCalcDocument, SELF, info.theShiftKey, info.theCmdKey);
- DoMouseCommand := aRowSelector;
- WITH fCalcDocument DO
- BEGIN
- fSelectionType := RowSelection;
- fColumnsView.SetEmptySelection(kHighlight);
- fColumnIsSelected := FALSE;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- FUNCTION TRowsView.DoSetCursor(localPoint: Point;
- cursorRgn: RgnHandle): BOOLEAN; OVERRIDE;
-
- BEGIN
- DoSetCursor := FALSE;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TRowsView.DrawCell(aCell: GridCell;
- aQDRect: Rect); OVERRIDE;
-
- VAR
- theString: Str255;
-
- BEGIN
- NumToString(aCell.v, theString);
- WITH aQDRect DO { aesthetic adjustment of the rect }
- top := top + 2;
- MADrawString(@theString, aQDRect, teJustCenter);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AFields}
-
- PROCEDURE TRowsView.Fields(PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- BEGIN
- DoToField('TRowsView', NIL, bClass);
- DoToField('fCalcDocument', @fCalcDocument, bObject);
- INHERITED Fields(DoToField);
- END;
-
- {***************************************************************************************************
- T C o l u m n s V i e w
- ***************************************************************************************************}
- {$S AOpen}
-
- PROCEDURE TColumnsView.IRes(itsDocument: TDocument;
- itsSuperView: TView;
- VAR itsParams: Ptr); OVERRIDE;
-
- BEGIN
- fCalcDocument := TCalcDocument(itsDocument);
- INHERITED IRes(itsDocument, itsSuperView, itsParams);
- SetRowHeight(1, fNumOfRows, kCellHeight);
- fCalcDocument.fColumnIsSelected := FALSE;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TColumnsView.AdornCol(aCol: INTEGER;
- area: Rect); OVERRIDE;
-
- BEGIN
- PenPat(black);
- PenSize(1, 1);
-
- { top line }
- MoveTo(area.left, area.top);
- LineTo(area.right - 1, area.top);
-
- { bottom line }
- MoveTo(area.left, area.bottom - 1);
- LineTo(area.right - 1, area.bottom - 1);
-
- { right line }
- MoveTo(area.right - 1, area.top);
- LineTo(area.right - 1, area.bottom - 1);
-
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TColumnsView.CoordToString(coord: INTEGER;
- VAR theString: Str255);
-
- BEGIN
- coord := coord - 1;
- IF coord < 26 THEN
- BEGIN
- theString := ' ';
- theString[1] := CHR(ORD('A') + coord);
- END
- ELSE
- BEGIN
- theString := ' ';
- theString[1] := CHR(ORD('A') + (coord DIV 26) - 1);
- theString[2] := CHR(ORD('A') + (coord MOD 26));
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ASelCommand}
-
- FUNCTION TColumnsView.DoMouseCommand(VAR theMouse: Point;
- VAR info: EventInfo;
- VAR hysteresis: Point): TCommand; OVERRIDE;
-
- VAR
- aColumnSelector: TColumnSelector;
- aColumnSizer: TColumnSizer;
- aRow: INTEGER;
- aCol: INTEGER;
- whichPart: GridViewPart;
- aCell: GridCell;
-
- BEGIN
- DoMouseCommand := NIL;
- whichPart := IdentifyPoint(theMouse, aRow, aCol);
- aCell.h := aCol;
- aCell.v := aRow;
-
- CASE whichPart OF
- inCell:
- BEGIN
- fCalcDocument.fColumnIsSelected := TRUE;
- NEW(aColumnSelector);
- FailNIL(aColumnSelector);
- aColumnSelector.IColumnSelector(fCalcDocument, SELF, info.theShiftKey, info.theCmdKey);
- DoMouseCommand := aColumnSelector;
- fCalcDocument.fSelectionType := ColumnSelection;
- END;
-
- inColumn, inVertex:
- BEGIN
- IF aCol > 1 THEN
- BEGIN
- NEW(aColumnSizer);
- FailNIL(aColumnSizer);
- aColumnSizer.IColumnSizer(fCalcDocument, aCol - 1);
- DoMouseCommand := aColumnSizer;
- END;
- END;
-
- OTHERWISE;
- END;
- fCalcDocument.fRowsView.SetEmptySelection(kHighlight);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- FUNCTION TColumnsView.DoSetCursor(localPoint: Point;
- cursorRgn: RgnHandle): BOOLEAN; OVERRIDE;
-
- VAR
- aRow: INTEGER;
- aCol: INTEGER;
- cellsExtent: VRect;
- cellsQDExtent, columnQDExtent: Rect;
-
- BEGIN
- DoSetCursor := FALSE;
-
- CASE IdentifyPoint(localPoint, aRow, aCol) OF
- badChoice: ;
- inColumn, inVertex:
- IF aCol > 1 THEN
- BEGIN
- DoSetCursor := TRUE;
- SetCursor(GetCursor(kColumnSizingCursor)^^);
- ColToVRect(Min(aCol, fNumOfCols), 1, cellsExtent);
- ViewToQDRect(cellsExtent, cellsQDExtent);
- columnQDExtent := cellsQDExtent;
-
- { Which edge is the mouse closer to? }
- IF abs(columnQDExtent.right - localPoint.h) < abs(columnQDExtent.left -
- localPoint.h) THEN
- columnQDExtent.left := columnQDExtent.right;
-
- columnQDExtent.left := columnQDExtent.left - fColInset DIV 2;
- columnQDExtent.right := columnQDExtent.left + fColInset;
- RectRgn(cursorRgn, columnQDExtent);
- END;
- inRow, inCell:
- BEGIN
- DoSetCursor := TRUE;
- SetCursor(arrow);
- ColToVRect(Min(aCol, fNumOfCols), 1, cellsExtent);
- InsetVRect(cellsExtent, fColInset DIV 2, 0); { Account for the column resizer }
- ViewToQDRect(cellsExtent, cellsQDExtent);
- RectRgn(cursorRgn, cellsQDExtent);
- END;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TColumnsView.DrawCell(aCell: GridCell;
- aQDRect: Rect); OVERRIDE;
-
- VAR
- theString: Str255;
-
- BEGIN
- CoordToString(aCell.h, theString);
- WITH aQDRect DO { aesthetic adjustment of the rect }
- top := top + 2;
- MADrawString(@theString, aQDRect, teJustCenter);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TColumnsView.ReSelect(cellRegion: RgnHandle);
-
- VAR
- aCell: GridCell;
- cellsInColumn: RgnHandle;
- cellsToSelect: RgnHandle;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE GetColumnCells(columnCell: GridCell);
-
- VAR
- aRect: Rect;
-
- BEGIN
- SetRect(aRect, columnCell.h, 1, columnCell.h + 1, fCalcDocument.fCellsView.fNumOfRows + 1);
- RectRgn(cellsInColumn, aRect);
- UnionRgn(cellsInColumn, cellsToSelect, cellsToSelect);
- END;
-
- BEGIN
- aCell := cellRegion^^.rgnBBox.topLeft;
- IF NOT EqualRect(cellRegion^^.rgnBBox, fSelections^^.rgnBBox) THEN
- BEGIN { selection has changed }
- WITH fCalcDocument DO
- BEGIN
- fCellsView.SetEmptySelection(kHighlight);
- fRowsView.SetEmptySelection(kHighlight);
- fColumnIsSelected := TRUE;
- END;
- SetSelection(cellRegion, kDontExtend, kHighlight, kSelect);
- cellsToSelect := MakeNewRgn;
- cellsInColumn := MakeNewRgn;
- EachSelectedCellDo(GetColumnCells); { add cells in the column to cellsToSelect }
- fCalcDocument.fCellsView.SetSelection(cellsToSelect, kDontExtend, kHighlight, kSelect);
- DisposeRgn(cellsToSelect);
- DisposeRgn(cellsInColumn);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AFields}
-
- PROCEDURE TColumnsView.Fields(PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- BEGIN
- DoToField('TColumnsView', NIL, bClass);
- DoToField('fCalcDocument', @fCalcDocument, bObject);
- INHERITED Fields(DoToField);
- END;
-
- {***************************************************************************************************
- T C a l c P r i n t H a n d l e r
- ***************************************************************************************************}
- {$S ANonRes}
-
- PROCEDURE TCalcPrintHandler.CalcViewPerPage(VAR amtPerPage: VPoint); OVERRIDE;
-
- VAR
- noOfRows: INTEGER;
-
- BEGIN
- INHERITED CalcViewPerPage(amtPerPage);
- noOfRows := amtPerPage.v DIV kCellHeight;
- amtPerPage.v := noOfRows * kCellHeight;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ANonRes}
-
- FUNCTION TCalcPrintHandler.DoMenuCommand(aCmdNumber: cmdNumber): TCommand; OVERRIDE;
- { Overridden to handle Print Selection. }
-
- BEGIN
- DoMenuCommand := NIL;
- fCmdNumber := aCmdNumber; { Save cmd number for GetPrintExtent }
- IF aCmdNumber = cPrintSelection THEN
- aCmdNumber := cPrint; { proceed like regular Print }
- DoMenuCommand := INHERITED DoMenuCommand(aCmdNumber);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ANonRes}
-
- PROCEDURE TCalcPrintHandler.DoSetupMenus; OVERRIDE;
- { Overridden to handle Print Selection. }
-
- BEGIN
- INHERITED DoSetupMenus;
- Enable(cPrintSelection, gCouldPrint & (fView <> NIL));
- END;
-
- {***************************************************************************************************
- T E n t r y V i e w
- ***************************************************************************************************}
- {$S AOpen}
-
- PROCEDURE TEntryView.IRes(itsDocument: TDocument;
- itsSuperView: TView;
- VAR itsParams: Ptr); OVERRIDE;
-
- VAR
- minSize: Point;
-
- BEGIN
- INHERITED IRes(NIL, itsSuperView, itsParams); { set itsDocument to NIL since this guy
- doesn't affect the document }
- fCalcDocument := TCalcDocument(itsDocument);
- fTouched := FALSE;
- fTEditing := FALSE;
- fFirstEdit := FALSE;
- fOldString := '';
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- FUNCTION TEntryView.DoKeyCommand(Ch: CHAR;
- aKeyCode: INTEGER;
- VAR info: EventInfo): TCommand; OVERRIDE;
-
- BEGIN
- { If this is the first character, wipe out old value and activate caret. }
- IF (NOT fTEditing) & ((Ch >= ' ') | (Ch = chBackspace)) THEN
- SetEditMode;
- DoKeyCommand := INHERITED DoKeyCommand(Ch, aKeyCode, info);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ASelCommand}
-
- FUNCTION TEntryView.DoMakeTypingCommand(Ch: CHAR): TTETypingCommand; OVERRIDE;
-
- VAR
- aTypingCommand: TCalcTypingCommand;
-
- BEGIN
- NEW(aTypingCommand);
- FailNIL(aTypingCommand);
- aTypingCommand.ITETypingCommand(SELF, Ch);
- DoMakeTypingCommand := aTypingCommand;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ASelCommand}
-
- FUNCTION TEntryView.DoMouseCommand(VAR theMouse: Point;
- VAR info: EventInfo;
- VAR hysteresis: Point): TCommand; OVERRIDE;
-
- BEGIN
- { If no characters typed, active caret, then handle mouse down. }
- IF NOT fTouched THEN
- InstallSelection(FALSE, TRUE);
- EditMode(TRUE);
- DoMouseCommand := INHERITED DoMouseCommand(theMouse, info, hysteresis);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TEntryView.DoSetupMenus; OVERRIDE;
-
- BEGIN
- { TTEView.DoSetupMenus will setup the Edit menu commands for us. }
- INHERITED DoSetupMenus;
-
- IF fTEditing THEN
- BEGIN
- SetEditCmdName(cCut, cCutText);
- SetEditCmdName(cCopy, cCopyText);
- SetEditCmdName(cClear, cClearText);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TEntryView.Draw(area: Rect); OVERRIDE;
-
- VAR
- r: Rect;
-
- BEGIN
- INHERITED Draw(area);
-
- { We want a rectangle around the whole view }
- PenSize(1, 1);
- PenPat(black);
- GetQDExtent(r);
- FrameRect(r);
-
- INHERITED Draw(area);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ASelCommand}
-
- PROCEDURE TEntryView.EditMode(editing: BOOLEAN);
-
- VAR
- lastCommand: TCommand;
-
- BEGIN
- fTEditing := editing;
- fFirstEdit := FALSE; { set to TRUE only by DoKeyCommand }
-
- IF editing THEN
- BEGIN
- {$Push} {$H-}
- GetAsString(fOldString); { save previous string for Undo/Redo }
- {$Pop}
- END
- ELSE
- BEGIN { disable undo/redo for TTECommands. ???
- There must be a better way! this is
- disgusting! }
- lastCommand := GetLastCommand;
- IF lastCommand <> NIL THEN
- IF GetSuperClassID(GetClassID(lastCommand)) = GetClassIDFromName('TTECommand') THEN
- lastCommand.fCanUndo := FALSE;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TEntryView.GetAsString(VAR theString: Str255);
-
- VAR
- theText: CharsHandle;
- numberOfChars: INTEGER;
- i: INTEGER;
-
- BEGIN
- theText := TEGetText(fHTE);
- numberOfChars := Min(255, GetHandleSize(Handle(theText)));
- theString[0] := CHR(numberOfChars);
- FOR i := 1 TO numberOfChars DO
- theString[i] := theText^^[i - 1];
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TEntryView.InstallSelection(wasActive, beActive: BOOLEAN); OVERRIDE;
-
- VAR
- r: Rect;
-
- BEGIN
- INHERITED InstallSelection(wasActive, beActive);
-
- TESetSelect(0, 0, fHTE);
- fTouched := beActive;
- IF Focus THEN
- BEGIN
- GetQDExtent(r);
- InsetRect(r, 2, 2);
- InvalidRect(r);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ASelCommand}
-
- PROCEDURE TEntryView.SetEditMode;
-
- BEGIN
- EditMode(TRUE); { sets fFirstEdit to FALSE }
- fFirstEdit := TRUE; { the only place it is set to TRUE }
- SetToString('');
- InstallSelection(FALSE, TRUE);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TEntryView.SetToString(theString: Str255);
-
- BEGIN
- IF Focus THEN;
- SetJustification(teJustSystem, kDontRedraw); { initialize text to system-justified }
- InstallSelection(TRUE, FALSE);
- TESetText(Ptr(ORD4(@theString) + 1), LENGTH(theString), fHTE);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TEntryView.SwapStrings;
-
- VAR
- newString: Str255;
-
- BEGIN
- newString := fOldString;
- {$Push} {$H-}
- GetAsString(fOldString);
- {$Pop}
- SetToString(newString);
- fTouched := TRUE;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AFields}
-
- PROCEDURE TEntryView.Fields(PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- BEGIN
- DoToField('TEntryView', NIL, bClass);
- DoToField('fCalcDocument', @fCalcDocument, bObject);
- DoToField('fTouched', @fTouched, bBoolean);
- DoToField('fTEditing', @fTEditing, bBoolean);
- DoToField('fFirstEdit', @fFirstEdit, bBoolean);
- DoToField('fOldString', @fOldString, bString);
- INHERITED Fields(DoToField);
- END;
-
- {***************************************************************************************************
- T C o o r d V i e w
- ***************************************************************************************************}
- {$S AOpen}
-
- PROCEDURE TCoordView.IRes(itsDocument: TDocument;
- itsSuperView: TView;
- VAR itsParams: Ptr); OVERRIDE;
-
- VAR
- minSize: Point;
-
- BEGIN
- fCalcDocument := TCalcDocument(itsDocument);
- INHERITED IRes(itsDocument, itsSuperView, itsParams);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCoordView.Draw(area: Rect);
-
- VAR
- aString, anotherString: Str255;
- aRect:Rect;
-
- BEGIN
- WITH fCalcDocument DO
- BEGIN
- IF fEditColumn > 0 THEN
- fColumnsView.CoordToString(fEditColumn, aString)
- ELSE
- aString := ' ';
-
- IF fEditRow > 0 THEN
- NumToString(fEditRow, anotherString)
- ELSE
- anotherString := ' ';
- END;
- aString := CONCAT(aString, anotherString);
- SetTheFont(kEntryFont, kEntryFontSize, [bold]);
- SetRect(aRect, 2, 0, 46, kEntryHeight);
- SmartDrawString(aString, aRect, teJustSystem);
-
- INHERITED Draw(area);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AFields}
-
- PROCEDURE TCoordView.Fields(PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- BEGIN
- DoToField('TCoordView', NIL, bClass);
- DoToField('fCalcDocument', @fCalcDocument, bObject);
- INHERITED Fields(DoToField);
- END;
-
- {***************************************************************************************************
- T C o l u m n
- ***************************************************************************************************}
- {$S ARes}
-
- PROCEDURE TColumn.Initialize; OVERRIDE;
- { Put the object into a known state from which it may be safely FREEd.
- (and hopefully a usable state) }
-
- BEGIN
- INHERITED Initialize;
-
- fNumber := 0;
- fFormat := gDefaultFormat;
- fWidth := kCellWidth;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TColumn.IColumn(number: INTEGER);
-
- BEGIN
- IObject;
-
- fNumber := number;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AFields}
-
- PROCEDURE TColumn.Fields(PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- BEGIN
- DoToField('TColumn', NIL, bClass);
- DoToField('fNumber', @fNumber, bInteger);
- {$Push} {$H-} { Because FormatFields is in a debugging
- (i.e. resident) segment) }
- FormatFields('fFormat', fFormat, DoToField);
- {$Pop}
- DoToField('fWidth', @fWidth, bInteger);
-
- INHERITED Fields(DoToField);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AReadFile}
-
- PROCEDURE TColumn.ReadFromDisk(theRefNum: INTEGER);
-
- VAR
- columnInfo: ColumnDiskInfo;
-
- BEGIN
- ReadBytes(theRefNum, SIZEOF(columnInfo), @columnInfo);
- WITH columnInfo DO
- BEGIN
- fNumber := number;
- fFormat := format;
- fWidth := width;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AClipBoard}
-
- PROCEDURE TColumn.ReadFromScrap(theScrap: Handle;
- VAR scrapOffset: LONGINT);
-
- VAR
- columnInfo: ColumnDiskInfo;
-
- BEGIN
- ReadScrap(theScrap, scrapOffset, @columnInfo, SIZEOF(columnInfo));
- WITH columnInfo DO
- BEGIN
- fNumber := number;
- fFormat := format;
- fWidth := width;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AWriteFile}
-
- PROCEDURE TColumn.WriteToDisk(theRefNum: INTEGER);
-
- VAR
- columnInfo: ColumnDiskInfo;
- theColumn: ColumnNumber;
-
- BEGIN
- theColumn := fNumber;
- WriteBytes(theRefNum, SIZEOF(ColumnNumber), @theColumn);
-
- WITH columnInfo DO
- BEGIN
- number := fNumber;
- format := fFormat;
- width := fWidth;
- END;
- WriteBytes(theRefNum, SIZEOF(columnInfo), @columnInfo);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AClipBoard}
-
- PROCEDURE TColumn.WriteToScrap(theScrap: Handle;
- VAR scrapOffset: LONGINT);
-
- VAR
- columnInfo: ColumnDiskInfo;
-
- BEGIN
- WITH columnInfo DO
- BEGIN
- number := fNumber;
- format := fFormat;
- width := fWidth;
- END;
- WriteScrap(theScrap, scrapOffset, @columnInfo, SIZEOF(columnInfo));
- END;
-
- {***************************************************************************************************
- T R o w
- ***************************************************************************************************}
- {$S ARes}
-
- PROCEDURE TRow.Initialize; OVERRIDE;
- { Put the object into a known state from which it may be safely FREEd.
- (and hopefully a usable state) }
-
- BEGIN
- INHERITED Initialize;
-
- fNumber := 0;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TRow.IRow(number: INTEGER);
-
- BEGIN
- IObject;
-
- fNumber := number;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AFields}
-
- PROCEDURE TRow.Fields(PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- BEGIN
- DoToField('TRow', NIL, bClass);
- DoToField('fNumber', @fNumber, bInteger);
- INHERITED Fields(DoToField)
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AReadFile}
-
- PROCEDURE TRow.ReadFromDisk(theRefNum: INTEGER);
-
- VAR
- RowInfo: RowDiskInfo;
-
- BEGIN
- ReadBytes(theRefNum, SIZEOF(RowInfo), @RowInfo);
- WITH RowInfo DO
- fNumber := number;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AClipBoard}
-
- PROCEDURE TRow.ReadFromScrap(theScrap: Handle;
- VAR scrapOffset: LONGINT);
-
- VAR
- RowInfo: RowDiskInfo;
-
- BEGIN
- ReadScrap(theScrap, scrapOffset, @RowInfo, SIZEOF(RowInfo));
- WITH RowInfo DO
- fNumber := number;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AWriteFile}
-
- PROCEDURE TRow.WriteToDisk(theRefNum: INTEGER);
-
- VAR
- RowInfo: RowDiskInfo;
- theRow: RowNumber;
-
- BEGIN
- theRow := fNumber;
- WriteBytes(theRefNum, SIZEOF(RowNumber), @theRow);
-
- WITH RowInfo DO
- number := fNumber;
- WriteBytes(theRefNum, SIZEOF(RowInfo), @RowInfo);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AClipBoard}
-
- PROCEDURE TRow.WriteToScrap(theScrap: Handle;
- VAR scrapOffset: LONGINT);
-
- VAR
- RowInfo: RowDiskInfo;
-
- BEGIN
- WITH RowInfo DO
- number := fNumber;
- WriteScrap(theScrap, scrapOffset, @RowInfo, SIZEOF(RowInfo));
- END;
-
- {***************************************************************************************************
- T C e l l
- ***************************************************************************************************}
- {$S ARes}
-
- PROCEDURE TCell.Initialize; OVERRIDE;
-
- BEGIN
- INHERITED Initialize;
-
- fCalcDocument := NIL;
- fDeleted := FALSE;
- fDependents := NIL;
- fReferences := NIL;
-
- fKind := EmptyCell;
- fError := NoError;
- fValue := 0.0;
- fValueString := '';
- fFormula := '';
- FailMemError;
-
- fRow := 0;
- fColumn := 0;
- fEvaluating := FALSE;
- fCalculating := FALSE;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCell.ICell(owningDocument: TCalcDocument;
- r: RowNumber;
- c: ColumnNumber);
-
- BEGIN
- IObject;
-
- fCalcDocument := owningDocument;
-
- fDependents := NewList;
- FailNIL(fDependents);
-
- fReferences := NewList;
- FailNIL(fReferences);
-
- {$IFC qDebug}
- fDependents.SetEltType('TCell');
- fReferences.SetEltType('TCell');
- {$ENDC}
-
- fRow := r;
- fColumn := c;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCell.Free;
-
- BEGIN
- FreeIfObject(fDependents);
- fDependents := NIL;
-
- FreeIfObject(fReferences);
- fReferences := NIL;
-
- INHERITED Free;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- FUNCTION TCell.Clone: TObject; OVERRIDE;
-
- VAR
- clonedCell: TCell;
-
- BEGIN
- clonedCell := TCell(INHERITED Clone);
- FailNIL(clonedCell);
-
- clonedCell.fDependents := NewList;
- FailNIL(clonedCell.fDependents);
-
- clonedCell.fReferences := NewList;
- FailNIL(clonedCell.fReferences);
-
- {$IFC qDebug}
- clonedCell.fDependents.SetEltType('TCell');
- clonedCell.fReferences.SetEltType('TCell');
- {$ENDC}
-
- Clone := TObject(clonedCell);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCell.CopyContents(sourceCell: TCell);
-
- BEGIN
- fKind := sourceCell.fKind;
- fFormula := sourceCell.fFormula;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCell.EvaluateFormula(DoReferences: BOOLEAN);
-
- VAR
- formulaLength: INTEGER;
- formulaIndex: INTEGER;
- theChar: CHAR;
- theValue: ValueType;
-
- {--------------------------------------------------------------------------------------------------}
-
- FUNCTION Factor(VAR theValue: ValueType): EvalResult;
- FORWARD;
-
- {--------------------------------------------------------------------------------------------------}
-
- FUNCTION Expression(VAR theValue: ValueType): EvalResult;
- FORWARD;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE GetNextChar;
-
- BEGIN
- REPEAT
- IF formulaIndex < formulaLength THEN
- BEGIN
- formulaIndex := formulaIndex + 1;
- theChar := fFormula[formulaIndex];
- END
- ELSE
- theChar := CHR(0);
- UNTIL theChar <> ' ';
- IF (theChar >= 'a') & (theChar <= 'z') THEN
- theChar := CHR(ORD(theChar) - 32);
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- FUNCTION DoInteger(VAR theInteger: INTEGER): EvalResult;
-
- BEGIN
- theInteger := 0;
- WHILE IsDigit(theChar) DO
- BEGIN
- theInteger := theInteger * 10 + ORD(theChar) - ORD('0');
- GetNextChar;
- END;
- DoInteger := NoError;
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- FUNCTION DoNumber(VAR theValue: ValueType): EvalResult;
- { DoNumber is called only when theChar is a numeric digit or a decimal point }
-
- VAR
- newIndex: INTEGER;
- decimalNumber: Decimal;
- IsValidNumber: BOOLEAN;
- startsWithDecPt: BOOLEAN;
- theFormula: Str255;
-
- BEGIN
- startsWithDecPt := (theChar = '.');
- newIndex := formulaIndex;
- theFormula := fFormula;
- Str2Dec(theFormula, newIndex, decimalNumber, IsValidNumber);
- { Str2Dec returns IsValidNumber = FALSE if the digits are followed by non-numerics like * }
- IF startsWithDecPt & (NOT IsValidNumber) THEN
- BEGIN
- GetNextChar;
- IF NOT IsDigit(theChar) THEN
- BEGIN
- DoNumber := BadNumber;
- EXIT(DoNumber);
- END;
- END;
- formulaIndex := newIndex - 1;
- GetNextChar;
- theValue := Dec2Num(decimalNumber);
- DoNumber := NoError;
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- FUNCTION DoCellReference(VAR theValue: ValueType): EvalResult;
-
- VAR
- theResult: EvalResult;
- r: INTEGER; { Can't use RowNumber because it may be }
- c: INTEGER; { …out of range }
- referencedCell: TCell;
- aRect: Rect;
-
- BEGIN
- theResult := NoError;
- aRect := fCalcDocument.fDimensions; { valid coordinates }
- c := 0;
- WHILE (theChar >= 'A') & (theChar <= 'Z') & (c <= aRect.right) DO
- BEGIN
- c := c * 26 + ORD(theChar) - ORD('A') + 1;
- GetNextChar;
- END;
- IF c > aRect.right THEN { column is out of range, so }
- r := 0 { …don't bother looking for row number }
- ELSE
- theResult := DoInteger(r);
- IF fCalcDocument.CellInRange(r, c, aRect) THEN
- BEGIN
- referencedCell := fCalcDocument.GetExistingCell(r - fCalcDocument.fRowOffset, c -
- fCalcDocument.fColumnOffset);
- IF referencedCell = NIL THEN { cell doesn't exist }
- theValue := 0
- ELSE
- BEGIN
- IF referencedCell.fEvaluating THEN
- theResult := SelfReference
- ELSE IF (referencedCell.fKind = ErrorCell) THEN
- theResult := ErrorCellReference
- ELSE IF (referencedCell.fKind = TextCell) THEN
- theValue := 0
- ELSE
- theValue := referencedCell.fValue;
-
- IF DoReferences THEN
- BEGIN
- fReferences.InsertLast(referencedCell);
- referencedCell.fDependents.InsertLast(SELF);
- END;
- END;
- END
- ELSE
- theResult := BadCellReference;
- DoCellReference := theResult;
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- FUNCTION Term(VAR theValue: ValueType): EvalResult;
-
- BEGIN
- IF theChar = '(' THEN
- BEGIN
- GetNextChar;
- Term := Expression(theValue);
- IF theChar = ')' THEN
- GetNextChar
- ELSE
- Term := MissingRightParen;
- END
- ELSE IF IsDigit(theChar) | (theChar = '.') THEN
- Term := DoNumber(theValue)
- ELSE IF (theChar >= 'A') & (theChar <= 'Z') THEN
- Term := DoCellReference(theValue)
- ELSE IF theChar = '+' THEN
- BEGIN
- GetNextChar;
- Term := Term(theValue);
- END
- ELSE IF theChar = '-' THEN
- BEGIN
- GetNextChar;
- Term := Term(theValue);
- theValue := - theValue;
- END
- ELSE
- Term := IllegalCharacter;
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- FUNCTION Factor(VAR theValue: ValueType): EvalResult;
-
- VAR
- theResult: EvalResult;
- factorValue: ValueType;
-
- BEGIN
- theResult := Term(theValue);
- IF theResult = NoError THEN
- IF theChar = '*' THEN
- BEGIN
- GetNextChar;
- theResult := Factor(factorValue);
- theValue := theValue * factorValue;
- END
- ELSE IF theChar = '/' THEN
- BEGIN
- GetNextChar;
- theResult := Factor(factorValue);
- theValue := theValue / factorValue;
- END;
- Factor := theResult;
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- FUNCTION Expression(VAR theValue: ValueType): EvalResult;
-
- VAR
- factorResult: EvalResult;
- factorValue: ValueType;
-
- BEGIN
- factorResult := Factor(theValue);
- IF factorResult = NoError THEN
- REPEAT
- IF theChar = '+' THEN
- BEGIN
- GetNextChar;
- factorResult := Factor(factorValue);
- theValue := theValue + factorValue;
- END
- ELSE IF theChar = '-' THEN
- BEGIN
- GetNextChar;
- factorResult := Factor(factorValue);
- theValue := theValue - factorValue;
- END;
- UNTIL (theChar <> '+') & (theChar <> '-');
- Expression := factorResult;
- END;
-
- BEGIN { EvaluateFormula }
- formulaLength := LENGTH(fFormula);
- formulaIndex := 0;
- GetNextChar;
- IF theChar IN ['=', '-', '+', '.', '0'..'9'] THEN
- BEGIN
- IF theChar = '=' THEN
- GetNextChar;
-
- fEvaluating := TRUE; { prevent self reference loop }
- fError := Expression(theValue);
- fEvaluating := FALSE;
-
- IF fError = NoError THEN
- BEGIN
- fValue := theValue;
- IF (formulaIndex <= formulaLength) & (theChar <> CHR(0)) THEN
- fError := GarbageAtEnd;
- END;
- IF fError = NoError THEN
- fKind := ValueCell
- ELSE
- fKind := ErrorCell;
- END
- ELSE
- fKind := TextCell;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCell.GetAsString(VAR theString: Str255);
-
- BEGIN
- theString := fFormula;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AWriteFile}
-
- FUNCTION TCell.GetDiskSize(infoRecordOnly: BOOLEAN): INTEGER;
-
- VAR
- cellSize: INTEGER;
-
- BEGIN
- cellSize := SIZEOF(CellDiskInfo) - SIZEOF(Str255) + LENGTH(fFormula) + 1;
- IF NOT infoRecordOnly THEN
- cellSize := cellSize + (fReferences.fSize + fDependents.fSize + 1) * SIZEOF(Point);
- GetDiskSize := cellSize;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCell.GetValueAsString(VAR theString: Str255);
-
- BEGIN
- CASE fKind OF
- TextCell:
- theString := fFormula;
- ValueCell:
- BEGIN
- IF fValueString = '' THEN
- ValueToString;
- theString := fValueString;
- END;
- ErrorCell:
- BEGIN
- NumToString(ORD(fError), theString);
- theString := CONCAT('**ERROR ', theString);
- END;
- OTHERWISE
- theString := '';
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AFields}
-
- PROCEDURE TCell.Fields(PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- VAR
- aString: Str255;
-
- BEGIN
- DoToField('TCell', NIL, bClass);
- DoToField('fDeleted', @fDeleted, bBoolean);
- DoToField('fCalcDocument', @fCalcDocument, bObject);
- DoToField('fDependents', @fDependents, bObject);
- DoToField('fReferences', @fReferences, bObject);
- DoToField('fRow', @fRow, bByte);
- DoToField('fColumn', @fColumn, bByte);
- CASE fKind OF
- EmptyCell:
- aString := 'Empty';
- ValueCell:
- aString := 'Value';
- TextCell:
- aString := 'Text';
- ErrorCell:
- aString := 'Error';
- END;
- DoToField('fKind', @aString, bString);
- CASE fError OF
- NoError:
- aString := 'None';
- MissingRightParen:
- aString := 'Missing right parenthesis';
- SelfReference:
- aString := 'Self reference';
- ErrorCellReference:
- aString := 'Reference to error cell';
- BadNumber:
- aString := 'Bad number';
- IllegalCharacter:
- aString := 'Illegal character';
- BadCellReference:
- aString := 'Bad cell reference';
- GarbageAtEnd:
- aString := 'Garbage at end';
- END;
- DoToField('fError', @aString, bString);
- DoToField('fValueString', @fValueString, bString);
- DoToField('fFormula', @fFormula, bString);
- DoToField('fEvaluating', @fEvaluating, bBoolean);
- DoToField('fCalculating', @fCalculating, bBoolean);
- INHERITED Fields(DoToField);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AFields}
-
- PROCEDURE TCell.GetInspectorName(VAR inspectorName: Str255); OVERRIDE;
-
- VAR
- aString, titleString: Str255;
-
- BEGIN
- IF IsObject(fCalcDocument.fColumnsView) THEN
- BEGIN
- fCalcDocument.fColumnsView.CoordToString(fColumn, aString);
- NumToString(fRow, inspectorName);
- fCalcDocument.GetInspectorName(titleString);
- inspectorName := CONCAT(titleString, ' ', aString, inspectorName);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCell.invalidate;
-
- VAR
- aCell: GridCell;
-
- BEGIN
- aCell.h := fColumn;
- aCell.v := fRow;
- fCalcDocument.fCellsView.InvalidateCell(aCell);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- FUNCTION TCell.IsEmpty: BOOLEAN;
-
- BEGIN
- IsEmpty := (fKind = EmptyCell) & (LENGTH(fFormula) = 0);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AReadFile}
-
- PROCEDURE TCell.ReadFromDisk(theRefNum: INTEGER);
-
- VAR
- cellLength: INTEGER;
- cellInfo: CellDiskInfo;
- referencedCell: TCell;
- refRow: RowNumber;
- refColumn: ColumnNumber;
- refIndex: INTEGER;
-
- BEGIN
- ReadBytes(theRefNum, SIZEOF(cellLength), @cellLength);
- ReadBytes(theRefNum, cellLength, @cellInfo);
-
- WITH cellInfo DO
- BEGIN
- fKind := kind;
- fError := error;
- fValue := value;
- fFormula := formula;
-
- FOR refIndex := 1 TO noOfReferences DO
- BEGIN
- ReadCellCoordinate(theRefNum, refRow, refColumn);
- referencedCell := fCalcDocument.GetCell(refRow, refColumn);
- fReferences.InsertLast(referencedCell);
- referencedCell.fDependents.InsertLast(SELF);
- END;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AClipBoard}
-
- PROCEDURE TCell.ReadFromScrap(theScrap: Handle;
- VAR scrapOffset: LONGINT);
-
- VAR
- cellLength: INTEGER;
- cellInfo: CellDiskInfo;
- referencedCell: TCell;
- cellCoord: Point;
- refIndex: INTEGER;
-
- BEGIN
- ReadScrap(theScrap, scrapOffset, @cellLength, SIZEOF(cellLength));
- ReadScrap(theScrap, scrapOffset, @cellInfo, cellLength);
-
- WITH cellInfo DO
- BEGIN
- fKind := kind;
- fError := error;
- fValue := value;
- fFormula := formula;
-
- FOR refIndex := 1 TO noOfReferences DO
- BEGIN
- ReadScrap(theScrap, scrapOffset, @cellCoord, SIZEOF(cellCoord));
- referencedCell := fCalcDocument.GetCell(cellCoord.v, cellCoord.h);
- fReferences.InsertLast(referencedCell);
- referencedCell.fDependents.InsertLast(SELF);
- END;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCell.Recalculate(forceAutomatic: BOOLEAN;
- setDependents: BOOLEAN);
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE RemoveDependent(theObject: TObject);
-
- BEGIN
- TCell(theObject).fDependents.Delete(TObject(SELF));
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE CalculateCell(theObject: TObject);
-
- VAR
- theCell: TCell;
- oldValue: ValueType;
- oldKind: KindOfCell;
- shouldInvalidate: BOOLEAN;
- wasLocked: BOOLEAN;
-
- BEGIN
- theCell := TCell(theObject);
-
- wasLocked := theCell.Lock(TRUE);
-
- WITH theCell DO
- BEGIN
- IF NOT fCalculating THEN
- BEGIN
- fCalculating := TRUE; { prevent circular reference loop }
- fValueString := '';
- oldValue := fValue;
- oldKind := fKind;
- EvaluateFormula(setDependents);
- shouldInvalidate := (oldValue <> fValue) | (oldKind <> fKind);
- IF shouldInvalidate | setDependents THEN
- BEGIN
- setDependents := FALSE;
- IF shouldInvalidate THEN
- theCell.invalidate;
- IF forceAutomatic | fCalcDocument.IsAutoCalc THEN
- fDependents.Each(CalculateCell);
- END;
- fCalculating := FALSE;
- END;
- END;
-
- wasLocked := theCell.Lock(wasLocked);
- END;
-
- BEGIN
- IF setDependents THEN
- BEGIN
- fReferences.Each(RemoveDependent);
- fReferences.DeleteAll;
- END;
- CalculateCell(TObject(SELF));
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCell.SetDeleteState(deleted: BOOLEAN);
-
- BEGIN
- fDeleted := deleted;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCell.SetToString(theString: Str255);
-
- VAR
- theOldString: Str255;
-
- BEGIN
- GetAsString(theOldString);
- IF theString <> theOldString THEN
- BEGIN
- fFormula := theString;
- fKind := EmptyCell; { Force Recalculate to invalidate the cell }
- Recalculate(NOT kForceAutomatic, kSetDependents); { we want to set new dependents }
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCell.ValueToString;
- { Fills fValueString with the string representation of the cell's value.
- The "general" format is complicated because we try to ensure that
- the string will fit within the cell's column width. Thus we have
- to figure out the appropriate representation for the value. }
-
- VAR
- aString: Str255;
- theFormat: DecForm;
- d: Decimal;
- i: INTEGER;
- len: INTEGER;
- sigDigits: INTEGER;
- leftDigits: INTEGER;
- rightDigits: INTEGER;
- width: INTEGER;
- digitWidth: INTEGER;
- dotWidth: INTEGER;
- eWidth: INTEGER;
- minusWidth: INTEGER;
- plusWidth: INTEGER;
- aColumn: TColumn;
- aValueType: ValueType;
-
- BEGIN
- aColumn := fCalcDocument.GetColumn(fColumn);
- WITH aColumn DO
- CASE fFormat.fStyle OF
- General:
- BEGIN
- SetTheFont(fFormat.fFontNumber, fFormat.fFontSize, fFormat.fFontStyle);
- digitWidth := CharWidth('0');
- dotWidth := CharWidth('.');
- eWidth := CharWidth('e');
- minusWidth := CharWidth('-');
- plusWidth := CharWidth('+');
- width := fCalcDocument.fCellsView.GetColWidth(fColumn) - (kCellHBorder * 2);
-
- theFormat := gGeneralFormat;
- aValueType := fValue;
- Num2Dec(theFormat, aValueType, d);
- aString := d.sig;
- len := LENGTH(aString);
-
- IF d.sgn = 1 THEN
- width := width - minusWidth;
-
- IF d.exp > 0 THEN
- { We've exceeded the precision of our value representation }
- BEGIN
- theFormat.Style := FloatDecimal;
- { account for '.' and '+e99' }
- width := width - dotWidth - CharWidth('+') - eWidth - digitWidth - digitWidth;
- theFormat.digits := Min(kValuePrecision, width DIV digitWidth);
- END
- ELSE
- BEGIN
-
- { determine number of significant digits }
- sigDigits := 1; { in case all digits are zero }
- FOR i := len DOWNTO 2 DO
- IF aString[i] <> '0' THEN
- BEGIN
- sigDigits := i;
- LEAVE;
- END;
-
- leftDigits := kValuePrecision + d.exp;
- rightDigits := sigDigits - leftDigits;
-
- IF leftDigits < sigDigits THEN
- width := width - dotWidth; { account for decimal point }
-
- IF leftDigits * digitWidth > width THEN
- BEGIN
- { We must convert to scientific notation }
-
- { account for decimal point and 'e9' }
- width := width - dotWidth - eWidth - digitWidth;
-
- { For positive numbers, SANE puts a space (' ') before
- the first significant digit. }
- IF d.sgn <> 1 THEN
- width := width - CharWidth(' ');
- IF d.exp < - kValuePrecision THEN
- width := width - minusWidth
- ELSE
- width := width - plusWidth;
- IF leftDigits > 10 THEN
- width := width - digitWidth; { account for double-digit exponents }
-
- theFormat.Style := FloatDecimal;
- theFormat.digits := Min(sigDigits, width DIV digitWidth);
- END
- ELSE
- BEGIN
- theFormat.Style := FixedDecimal;
- theFormat.digits := Min((width - (leftDigits * digitWidth) - dotWidth) DIV
- digitWidth, rightDigits);
- IF theFormat.digits < 0 THEN
- theFormat.digits := 0;
- END;
- END;
- END;
- DecimalStyle:
- theFormat := gDecimalFormat;
- NoDecimal:
- theFormat := gNoDecimalFormat;
- Scientific:
- theFormat := gScientificFormat;
- END;
-
- aValueType := fValue;
- Num2Str(theFormat, aValueType, DecStr(aString));
- IF aString[1] = ' ' THEN
- Delete(aString, 1, 1); { Remove leading space }
- fValueString := Copy(aString, 1, Min(kMaxValueLength, LENGTH(aString)));
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AWriteFile}
-
- PROCEDURE TCell.WriteToDisk(theRefNum: INTEGER);
-
- VAR
- cellInfo: CellDiskInfo;
- cellLength: INTEGER;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE WriteCellCoordinate(theObject: TObject);
-
- VAR
- cellCoordinate: Point;
-
- BEGIN
- cellCoordinate.v := TCell(theObject).fRow;
- cellCoordinate.h := TCell(theObject).fColumn;
- WriteBytes(theRefNum, SIZEOF(cellCoordinate), @cellCoordinate);
- END;
-
- BEGIN
- WriteCellCoordinate(TObject(SELF));
- cellLength := GetDiskSize(TRUE); { don't include ref's & dependents }
- WriteBytes(theRefNum, SIZEOF(cellLength), @cellLength);
- WITH cellInfo DO
- BEGIN
- kind := fKind;
- error := fError;
- value := fValue;
- noOfReferences := fReferences.fSize;
- formula := fFormula;
-
- WriteBytes(theRefNum, cellLength, @cellInfo);
-
- fReferences.Each(WriteCellCoordinate);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AClipBoard}
-
- PROCEDURE TCell.WriteToScrap(theScrap: Handle;
- VAR scrapOffset: LONGINT);
-
- VAR
- cellInfo: CellDiskInfo;
- cellLength: INTEGER;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE WriteCellCoordinate(theObject: TObject);
-
- VAR
- cellCoordinate: Point;
-
- BEGIN
- cellCoordinate.v := TCell(theObject).fRow;
- cellCoordinate.h := TCell(theObject).fColumn;
- WriteScrap(theScrap, scrapOffset, @cellCoordinate, SIZEOF(cellCoordinate));
- END;
-
- BEGIN
- WriteCellCoordinate(TObject(SELF));
- cellLength := GetDiskSize(TRUE); { don't include ref's & dependents }
- WriteScrap(theScrap, scrapOffset, @cellLength, SIZEOF(cellLength));
- WITH cellInfo DO
- BEGIN
- kind := fKind;
- error := fError;
- value := fValue;
- noOfReferences := 0; { fReferences.fSize }
- formula := fFormula;
-
- WriteScrap(theScrap, scrapOffset, @cellInfo, cellLength);
- END;
- END;
-
- {***************************************************************************************************
- T C a l c S e l e c t C o m m a n d
- ***************************************************************************************************}
- {$S ASelCommand}
-
- PROCEDURE TCalcSelectCommand.ICalcSelectCommand(itsDocument: TCalcDocument;
- itsView: TGridView;
- theShiftKey, theCmdKey: BOOLEAN);
-
- BEGIN
- ICellSelectCommand(itsView, theShiftKey, theCmdKey);
- fCalcDocument := itsDocument;
- itsDocument.fEntryView.EditMode(FALSE);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCalcSelectCommand.ComputeNewSelection(VAR clickedCell: GridCell); OVERRIDE;
-
- VAR
- r: Rect;
-
- BEGIN
- IF fGridView.CanSelectCell(clickedCell) THEN
- BEGIN
- Pt2Rect(fAnchorCell, clickedCell, r);
- r.right := r.right + 1;
- r.bottom := r.bottom + 1;
- RectRgn(fThisSelection, r);
- IF fCmdKey THEN
- IF fDeselecting THEN
- DiffRgn(fPrevSelection, fThisSelection, fThisSelection)
- ELSE
- UnionRgn(fPrevSelection, fThisSelection, fThisSelection);
- END;
- END;
-
- {***************************************************************************************************
- T R o W S e l e c t o r
- ***************************************************************************************************}
- {$S ASelCommand}
-
- PROCEDURE TRowSelector.IRowSelector(itsDocument: TCalcDocument;
- itsView: TGridView;
- theShiftKey, theCmdKey: BOOLEAN);
-
- VAR
- aCellSelector: TCalcSelectCommand;
-
- BEGIN
- fCalcDocument := itsDocument;
- IF fCalcDocument.fSelectionType <> RowSelection THEN
- theCmdKey := FALSE;
- ICellSelectCommand(itsView, theShiftKey, theCmdKey);
-
- NEW(aCellSelector);
- FailNIL(aCellSelector);
- aCellSelector.ICalcSelectCommand(itsDocument, itsDocument.fCellsView, theShiftKey, theCmdKey);
- fCellSelector := aCellSelector;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TRowSelector.Free; OVERRIDE;
-
- BEGIN
- FreeIfObject(fCellSelector);
- fCellSelector := NIL;
-
- INHERITED Free;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TRowSelector.ComputeAnchorCell(VAR clickedCell: GridCell); OVERRIDE;
-
- BEGIN
- INHERITED ComputeAnchorCell(clickedCell);
- fAnchorCell.h := 1;
-
- clickedCell.h := 1;
- fCellSelector.ComputeAnchorCell(clickedCell);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TRowSelector.ComputeNewSelection(VAR clickedCell: GridCell); OVERRIDE;
-
- VAR
- r: Rect;
-
- BEGIN
- clickedCell.h := fGridView.fNumOfCols;
- INHERITED ComputeNewSelection(clickedCell);
-
- clickedCell.h := fCalcDocument.fNoOfColumns;
- fCellSelector.ComputeNewSelection(clickedCell);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TRowSelector.DoIt; OVERRIDE;
-
- BEGIN
- INHERITED DoIt;
- fCellSelector.DoIt;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- FUNCTION TRowSelector.TrackMouse(aTrackPhase: TrackPhase;
- VAR anchorPoint, previousPoint, nextPoint: VPoint;
- mouseDidMove: BOOLEAN): TCommand; OVERRIDE;
-
- VAR
- clickedCell: GridCell;
-
- BEGIN
- IF mouseDidMove THEN
- BEGIN
- clickedCell := fGridView.VPointToCell(nextPoint);
- IF aTrackPhase = TrackPress THEN
- BEGIN
- ComputeAnchorCell(clickedCell);
- IF fCmdKey THEN
- BEGIN
- fDeselecting := PtInRgn(fAnchorCell, fGridView.fSelections);
- fCellSelector.fDeselecting := fDeselecting;
- END;
- END;
-
- IF LONGINT(clickedCell) <> LONGINT(fPrevCell) THEN
- BEGIN
- ComputeNewSelection(clickedCell);
- HighlightNewSelection;
- fCellSelector.HighlightNewSelection;
-
- CopyRgn(fThisSelection, fPrevSelection);
- fPrevCell := clickedCell;
- WITH fCellSelector DO
- BEGIN
- CopyRgn(fThisSelection, fPrevSelection);
- fPrevCell := clickedCell;
- END;
- END;
- END;
- TrackMouse := SELF;
- END;
-
- {***************************************************************************************************
- T C o l u m n S e l e c t o r
- ***************************************************************************************************}
- {$S ASelCommand}
-
- PROCEDURE TColumnSelector.IColumnSelector(itsDocument: TCalcDocument;
- itsView: TGridView;
- theShiftKey, theCmdKey: BOOLEAN);
-
- VAR
- aCellSelector: TCalcSelectCommand;
-
- BEGIN
- fCalcDocument := itsDocument;
- IF fCalcDocument.fSelectionType <> ColumnSelection THEN
- theCmdKey := FALSE;
- ICellSelectCommand(itsView, theShiftKey, theCmdKey);
-
- NEW(aCellSelector);
- FailNIL(aCellSelector);
- aCellSelector.ICalcSelectCommand(itsDocument, itsDocument.fCellsView, theShiftKey, theCmdKey);
- fCellSelector := aCellSelector;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TColumnSelector.Free; OVERRIDE;
-
- BEGIN
- FreeIfObject(fCellSelector);
- fCellSelector := NIL;
-
- INHERITED Free;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TColumnSelector.ComputeAnchorCell(VAR clickedCell: GridCell); OVERRIDE;
-
- BEGIN
- INHERITED ComputeAnchorCell(clickedCell);
- fAnchorCell.v := 1;
-
- clickedCell.v := 1;
- fCellSelector.ComputeAnchorCell(clickedCell);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TColumnSelector.ComputeNewSelection(VAR clickedCell: GridCell); OVERRIDE;
-
- VAR
- r: Rect;
-
- BEGIN
- clickedCell.v := fGridView.fNumOfRows;
- INHERITED ComputeNewSelection(clickedCell);
-
- clickedCell.v := fCalcDocument.fNoOfRows;
- fCellSelector.ComputeNewSelection(clickedCell);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TColumnSelector.DoIt; OVERRIDE;
-
- BEGIN
- INHERITED DoIt;
- fCellSelector.DoIt;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- FUNCTION TColumnSelector.TrackMouse(aTrackPhase: TrackPhase;
- VAR anchorPoint, previousPoint, nextPoint: VPoint;
- mouseDidMove: BOOLEAN): TCommand; OVERRIDE;
-
- VAR
- clickedCell: GridCell;
-
- BEGIN
- IF mouseDidMove THEN
- BEGIN
- clickedCell := fGridView.VPointToCell(nextPoint);
- IF aTrackPhase = TrackPress THEN
- BEGIN
- ComputeAnchorCell(clickedCell);
- IF fCmdKey THEN
- BEGIN
- fDeselecting := PtInRgn(fAnchorCell, fGridView.fSelections);
- fCellSelector.fDeselecting := fDeselecting;
- END;
- END;
-
- IF LONGINT(clickedCell) <> LONGINT(fPrevCell) THEN
- BEGIN
- ComputeNewSelection(clickedCell);
- HighlightNewSelection;
- fCellSelector.HighlightNewSelection;
-
- CopyRgn(fThisSelection, fPrevSelection);
- fPrevCell := clickedCell;
- WITH fCellSelector DO
- BEGIN
- CopyRgn(fThisSelection, fPrevSelection);
- fPrevCell := clickedCell;
- END;
- END;
- END;
- TrackMouse := SELF;
- END;
-
- {***************************************************************************************************
- T C o l u m n F o r m a t t e r
- ***************************************************************************************************}
- {$S ASelCommand}
-
- PROCEDURE TColumnFormatter.IFormatter(itsDocument: TCalcDocument;
- itsCommand: INTEGER);
-
- VAR
- fi: FailInfo;
-
- PROCEDURE HdlAllocationFailure(error: OSErr; message: LONGINT);
-
- BEGIN
- Free;
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE SaveFormat(aCell: GridCell);
-
- VAR
- theColumn: TColumn;
-
- BEGIN
- theColumn := fCalcDocument.GetColumn(aCell.h);
- theColumn.fOldFormat := theColumn.fFormat;
- END;
-
- BEGIN
- ICommand(itsCommand, itsDocument, itsDocument.fCellsView,
- itsDocument.fColumnsView.GetScroller(TRUE));
- fCalcDocument := itsDocument;
- CatchFailures(fi, HdlAllocationFailure);
- fSelection := MakeNewRgn; { copy the current selection region }
- CopyRgn(itsDocument.fColumnsView.fSelections, fSelection);
- Success(fi);
- fCalcDocument.fColumnsView.EachSelectedCellDo(SaveFormat);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TColumnFormatter.DoIt; OVERRIDE;
-
- PROCEDURE SetFormat(aCell: GridCell);
-
- VAR
- theColumn: TColumn;
-
- BEGIN
- theColumn := fCalcDocument.GetColumn(aCell.h);
- WITH theColumn.fFormat DO
- CASE fCmdNumber OF
- cGeneral:
- fStyle := General;
- cNoDecimal:
- fStyle := NoDecimal;
- cDecimal:
- fStyle := DecimalStyle;
- cScientific:
- fStyle := Scientific;
- cSystemJustify:
- fJustification := teJustSystem;
- cForceLeftJustify:
- fJustification := teForceLeft;
- cRightJustify:
- fJustification := TEJustRight;
- cCenter:
- fJustification := TEJustCenter;
- END;
- END;
-
- BEGIN
- fCalcDocument.fColumnsView.EachSelectedCellDo(SetFormat);
- IF (fCmdNumber >= cGeneral) & (fCmdNumber <= cScientific) THEN { Style change }
- fCalcDocument.DoRecalculate(NOT kForceAutomatic, NOT kSetDependents);
- fCalcDocument.fCellsView.InvalidateSelection;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TColumnFormatter.Free; OVERRIDE;
-
- BEGIN
- IF fSelection <> NIL THEN
- DisposeRgn(fSelection);
- fSelection := NIL;
-
- INHERITED Free;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TColumnFormatter.RedoIt; OVERRIDE;
-
- BEGIN
- fCalcDocument.fColumnsView.ReSelect(fSelection);
- DoIt;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TColumnFormatter.UndoIt; OVERRIDE;
-
- PROCEDURE RestoreFormat(aCell: GridCell);
-
- VAR
- theColumn: TColumn;
-
- BEGIN
- theColumn := fCalcDocument.GetColumn(aCell.h);
- theColumn.fFormat := theColumn.fOldFormat;
- END;
-
- BEGIN
- WITH fCalcDocument.fColumnsView DO
- BEGIN
- ReSelect(fSelection);
- EachSelectedCellDo(RestoreFormat);
- END;
- IF (fCmdNumber >= cGeneral) & (fCmdNumber <= cScientific) THEN { Style change }
- fCalcDocument.DoRecalculate(NOT kForceAutomatic, NOT kSetDependents);
- fCalcDocument.fCellsView.InvalidateSelection;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AFields}
-
- PROCEDURE TColumnFormatter.Fields(PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- BEGIN
- DoToField('TColumnFormatter', NIL, bClass);
- DoToField('fCalcDocument', @fCalcDocument, bObject);
- INHERITED Fields(DoToField);
- END;
-
- {***************************************************************************************************
- T C o l u m n S i z e r
- ***************************************************************************************************}
- {$S ASelCommand}
-
- PROCEDURE TColumnSizer.IColumnSizer(itsDocument: TCalcDocument;
- c: ColumnNumber);
-
- VAR
- colRect: VRect;
-
- BEGIN
- ICommand(cSizeColumn, itsDocument, itsDocument.fCellsView,
- itsDocument.fColumnsView.GetScroller(TRUE));
- fConstrainsMouse := TRUE;
- fCalcDocument := itsDocument;
- fCellsView := itsDocument.fCellsView;
- fColumn := itsDocument.GetColumn(c);
- fNewWidth := fCellsView.GetColWidth(fColumn.fNumber);
- fOldWidth := fNewWidth;
- fCellsView.ColToVRect(fColumn.fNumber, 1, colRect);
- fLeftEdge := colRect.left;
- fViewConstrain := FALSE; { So that rightmost column can grow }
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- FUNCTION TColumnSizer.TrackMouse(aTrackPhase: TrackPhase;
- VAR anchorPoint, previousPoint, nextPoint: VPoint;
- mouseDidMove: BOOLEAN): TCommand; OVERRIDE;
-
- BEGIN
- fNewWidth := Min(nextPoint.h - fLeftEdge, kTELength);
- fNewWidth := Max(fNewWidth, 10);
- TrackMouse := SELF;
- nextPoint.h := Min(nextPoint.h, fLeftEdge + kTELength);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TColumnSizer.TrackFeedback(anchorPoint, nextPoint: VPoint;
- turnItOn, mouseDidMove: BOOLEAN); OVERRIDE;
-
- VAR
- viewedRect: Rect;
- pState: PenState;
-
- BEGIN
- IF mouseDidMove THEN
- BEGIN
- GetPenState(pState);
- PenPat(black);
-
- fCellsView.GetQDExtent(viewedRect);
-
- MoveTo(Min(nextPoint.h, fLeftEdge + kTELength), viewedRect.top);
- Line(0, viewedRect.bottom - viewedRect.top);
- SetPenState(pState);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TColumnSizer.TrackConstrain(anchorPoint, previousPoint: VPoint;
- VAR nextPoint: VPoint); OVERRIDE;
-
- BEGIN
- IF nextPoint.h < fLeftEdge + 10 THEN
- nextPoint.h := fLeftEdge + 10
- ELSE
- nextPoint.h := Min(nextPoint.h, fLeftEdge + kTELength);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TColumnSizer.SetColumnWidth(newWidth: INTEGER);
-
- BEGIN
- IF newWidth > kTELength THEN
- BEGIN
- newWidth := kTELength;
- fNewWidth := kTELength;
- END
- ELSE IF newWidth < 10 THEN
- newWidth := 10;
-
- fCellsView.SetColWidth(fColumn.fNumber, 1, newWidth);
- fCalcDocument.fColumnsView.SetColWidth(fColumn.fNumber, 1, newWidth);
- fColumn.fWidth := newWidth;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TColumnSizer.DoIt; OVERRIDE;
-
- VAR
- minToSee: Point;
- aRect: VRect;
-
- BEGIN
- SetColumnWidth(fNewWidth);
-
- fCellsView.ColToVRect(fColumn.fNumber, 1, aRect);
- WITH aRect DO
- SetPt(minToSee, right - left, bottom - top);
- fCellsView.RevealRect(aRect, minToSee, TRUE);
-
- fCalcDocument.fColumnsView.ColToVRect(fColumn.fNumber, 1, aRect);
- WITH aRect DO
- SetPt(minToSee, right - left, bottom - top);
- fCalcDocument.fColumnsView.RevealRect(aRect, minToSee, TRUE);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TColumnSizer.UndoIt; OVERRIDE;
-
- BEGIN
- SetColumnWidth(fOldWidth);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TColumnSizer.RedoIt; OVERRIDE;
-
- BEGIN
- DoIt;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AFields}
-
- PROCEDURE TColumnSizer.Fields(PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- BEGIN
- DoToField('TColumnSizer', NIL, bClass);
- DoToField('fCalcDocument', @fCalcDocument, bObject);
- DoToField('fCellsView', @fCellsView, bObject);
- DoToField('fLeftEdge', @fLeftEdge, bInteger);
- DoToField('fColumn', @fColumn, bObject);
- DoToField('fNewWidth', @fNewWidth, bInteger);
- DoToField('fOldWidth', @fOldWidth, bInteger);
- INHERITED Fields(DoToField);
- END;
-
- {***************************************************************************************************
- T C a l c T y p i n g C o m m a n d
- ***************************************************************************************************}
- {$S ADoCommand}
-
- PROCEDURE TCalcTypingCommand.ITETypingCommand(itsTEView: TTEView;
- itsFirstChar: CHAR); OVERRIDE;
-
- BEGIN
- fCellsView := TEntryView(itsTEView).fCalcDocument.fCellsView;
- fTargetCell := fCellsView.FirstSelectedCell;
- INHERITED ITETypingCommand(itsTEView, itsFirstChar);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCalcTypingCommand.AddCharacter(aChar: CHAR); OVERRIDE;
- { Switch the entry view from left to right justification when the typed characters overflow the
- entry box, and switch back to left justification if the text shrinks enough }
-
- VAR
- selRight: INTEGER;
-
- {--------------------------------------------------------------------------------------------------}
-
- FUNCTION AddCharWidths: INTEGER;
-
- VAR
- aString: Str255;
-
- BEGIN
- GetIText(fHTE^^.hText, aString);
- AddCharWidths := StringWidth(aString);
- END;
-
- BEGIN
- IF (aChar <> chBackspace) & (fTEView.fJustification = TEJustLeft) THEN
- BEGIN
- selRight := fHTE^^.selRect.right;
- IF (selRight < 0) | (selRight > fHTE^^.destRect.right) THEN
- selRight := fHTE^^.selPoint.h;
- IF selRight + CharWidth(aChar) > fHTE^^.destRect.right THEN
- fTEView.SetJustification(TEJustRight, kDontRedraw);
- END;
-
- INHERITED AddCharacter(aChar);
-
- IF (aChar = chBackspace) & (fTEView.fJustification = TEJustRight) THEN
- IF AddCharWidths < LengthRect(fHTE^^.destRect, h) THEN
- fTEView.SetJustification(TEJustLeft, kRedraw);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCalcTypingCommand.UndoIt; OVERRIDE;
- { If the selection has changed since this command was created, restore it to the
- target cell before Undoing. }
-
- VAR
- entryView: TEntryView;
-
- BEGIN
- fCellsView.ReSelectCell(fTargetCell); { make sure fTargetCell is selected }
- entryView := TEntryView(fTEView);
- IF (entryView.fTEditing) & (NOT entryView.fFirstEdit) THEN
- INHERITED UndoIt { TTE undo }
- ELSE
- BEGIN
- entryView.SwapStrings; { exchange current and saved strings }
- fCellsView.SetCell(fTargetCell); { change fTargetCell's contents and redraw
- it }
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCalcTypingCommand.RedoIt; OVERRIDE;
- { If the selection has changed since this command was created, restore it to the
- target cell before Redoing. }
-
- VAR
- entryView: TEntryView;
-
- BEGIN
- fCellsView.ReSelectCell(fTargetCell); { make sure fTargetCell is selected }
- entryView := TEntryView(fTEView);
- IF (entryView.fTEditing) & (NOT entryView.fFirstEdit) THEN
- INHERITED RedoIt { TTE redo }
- ELSE
- BEGIN
- entryView.SwapStrings; { exchange current and saved strings }
- fCellsView.SetCell(fTargetCell); { change fTargetCell's contents and redraw
- it }
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AFields}
-
- PROCEDURE TCalcTypingCommand.Fields(PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- BEGIN
- DoToField('TCalcTypingCommand', NIL, bClass);
- DoToField('fCellsView', @fCellsView, bObject);
- DoToField('fTargetCell', @fTargetCell, bPoint);
- INHERITED Fields(DoToField);
- END;
-
- {***************************************************************************************************
- T C e l l E d i t C o m m a n d
- ***************************************************************************************************}
- {$S ASelCommand}
-
- PROCEDURE TCellEditCommand.ICellEditCommand(itsDocument: TCalcDocument;
- itsCommand: INTEGER);
-
- VAR
- fi: FailInfo;
-
- PROCEDURE HdlAllocationFailure(error: OSErr; message: LONGINT);
-
- BEGIN
- Free;
- END;
-
- BEGIN
- ICommand(itsCommand, itsDocument, itsDocument.fCellsView, NIL);
- fCalcDocument := itsDocument;
- CatchFailures(fi, HdlAllocationFailure);
- fSelection := MakeNewRgn; { copy the current selection region }
- Success(fi);
- CopyRgn(itsDocument.fCellsView.fSelections, fSelection);
- fChangesClipboard := itsCommand <> cClear;
- fCausesChange := itsCommand <> cCopy;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ARes}
-
- PROCEDURE TCellEditCommand.Free; OVERRIDE;
-
- BEGIN
- IF fSelection <> NIL THEN
- DisposeRgn(fSelection);
- fSelection := NIL;
-
- INHERITED Free;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellEditCommand.CopySelection;
-
- VAR
- clipDocument: TCalcDocument;
- clipView: TCellsView;
- clipRect: Rect;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE CopyRowToClipboard(aCell: GridCell);
-
- VAR
- newRow: TRow;
-
- BEGIN
- newRow := TRow(fCalcDocument.GetRow(aCell.v).Clone);
- newRow.fNumber := newRow.fNumber - clipDocument.fRowOffset;
- clipDocument.AddRow(newRow);
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE CopyColumnToClipboard(aCell: GridCell);
-
- VAR
- newColumn: TColumn;
-
- BEGIN
- newColumn := TColumn(fCalcDocument.GetColumn(aCell.h).Clone);
- newColumn.fNumber := newColumn.fNumber - clipDocument.fColumnOffset;
- clipDocument.AddColumn(newColumn);
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE CopyCellToClipboard(aCell: GridCell);
-
- VAR
- newCell: TCell;
- oldCell: TCell;
-
- BEGIN
- oldCell := fCalcDocument.GetExistingCell(aCell.v, aCell.h);
- IF oldCell <> NIL THEN
- BEGIN
- newCell := TCell(oldCell.Clone);
- clipDocument.AddCell(newCell, newCell.fRow - clipDocument.fRowOffset, newCell.fColumn -
- clipDocument.fColumnOffset);
- END;
- END;
-
- BEGIN
- NEW(clipDocument);
- FailNIL(clipDocument);
- clipRect := fSelection^^.rgnBBox;
- clipRect.bottom := clipRect.bottom - 1;
- clipRect.right := clipRect.right - 1;
- clipDocument.ICalcDocument(clipRect);
- clipDocument.DoInitialState;
-
- fCalcDocument.fRowsView.EachSelectedCellDo(CopyRowToClipboard);
- fCalcDocument.fColumnsView.EachSelectedCellDo(CopyColumnToClipboard);
- fCalcDocument.fCellsView.EachSelectedCellDo(CopyCellToClipboard);
-
- NEW(clipView);
- FailNIL(clipView);
- clipView.ICellsView(clipDocument, TRUE, NIL);
- clipDocument.fCellsView := clipView;
- gApplication.ClaimClipboard(clipView);
- clipView.AdjustSize;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellEditCommand.DeleteSelection;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE DeleteCell(aCell: GridCell);
-
- BEGIN
- fCalcDocument.DeleteCell(aCell.v, aCell.h);
- END;
-
- BEGIN
- fCalcDocument.fCellsView.EachSelectedCellDo(DeleteCell);
- fCalcDocument.DoRecalculate(NOT kForceAutomatic, NOT kSetDependents);
- fCalcDocument.fCellsView.InvalidateSelection;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellEditCommand.RestoreSelection;
-
- VAR
- firstCell: GridCell;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE RestoreCell(aCell: GridCell);
-
- BEGIN
- fCalcDocument.UndeleteCell(aCell.v, aCell.h);
- END;
-
- BEGIN
- fCalcDocument.fCellsView.EachSelectedCellDo(RestoreCell);
- fCalcDocument.DoRecalculate(NOT kForceAutomatic, NOT kSetDependents);
- fCalcDocument.fCellsView.InvalidateSelection;
-
- firstCell := fCalcDocument.fCellsView.FirstSelectedCell;
- fCalcDocument.SetEntry(firstCell.v, firstCell.h); { update entry view }
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellEditCommand.ReSelect;
-
- BEGIN
- fCalcDocument.fCellsView.ReSelect(fSelection);
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellEditCommand.DoIt;
-
- BEGIN
- IF fCmdNumber <> cClear THEN
- CopySelection;
- IF fCmdNumber <> cCopy THEN
- DeleteSelection;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellEditCommand.UndoIt;
- { If the user has changed the selection since this command was created,
- restore it before Undoing so that the correct cells are affected. }
-
- BEGIN
- IF fCmdNumber <> cCopy THEN
- BEGIN
- ReSelect; { restore command's original selection }
- RestoreSelection;
- fCalcDocument.fCellsView.ScrollSelectionIntoView(TRUE);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellEditCommand.RedoIt;
- { If the user has changed the selection since this command was created,
- restore it before Redoing so that the correct cells are affected. }
-
- BEGIN
- IF fCmdNumber <> cCopy THEN
- BEGIN
- ReSelect; { restore command's original selection }
- DeleteSelection;
- fCalcDocument.fCellsView.ScrollSelectionIntoView(TRUE);
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellEditCommand.Commit;
-
- BEGIN
- fCalcDocument.FreeDeletedCells;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AFields}
-
- PROCEDURE TCellEditCommand.Fields(PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- BEGIN
- DoToField('TCellEditCommand', NIL, bClass);
- DoToField('fCalcDocument', @fCalcDocument, bObject);
- DoToField('fSelection', @fSelection, bRgnHandle);
- INHERITED Fields(DoToField);
- END;
-
- {***************************************************************************************************
- T C e l l P a s t e C o m m a n d
- ***************************************************************************************************}
- {$S ASelCommand}
-
- PROCEDURE TCellPasteCommand.ICellPasteCommand(itsDocument: TCalcDocument);
-
- VAR
- fi: FailInfo;
-
- PROCEDURE HdlAllocationFailure(error: OSErr; message: LONGINT);
-
- BEGIN
- Free;
- END;
-
- BEGIN
- {$IFC qDebug}
- IF NOT Member(gClipView, TCellsView) THEN
- ProgramBreak('Attempt to paste a non-TCellsView clipboard');
- {$ENDC}
- ICommand(cPaste, itsDocument, itsDocument.fCellsView, NIL);
- fCalcDocument := itsDocument;
- CatchFailures(fi, HdlAllocationFailure);
- fSelection := MakeNewRgn; { copy the current selection region }
- Success(fi);
- CopyRgn(itsDocument.fCellsView.fSelections, fSelection);
- fClipDocument := TCellsView(gClipView).fCalcDocument;
- fReplacedCells := NewList;
- FailNIL(fReplacedCells);
- {$IFC qDebug}
- fReplacedCells.SetEltType('TCell');
- {$ENDC}
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellPasteCommand.Free; OVERRIDE;
-
- BEGIN
- IF fSelection <> NIL THEN
- DisposeRgn(fSelection);
- fSelection := NIL;
-
- fReplacedCells := FreeListIfObject(fReplacedCells);
-
- INHERITED Free;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellPasteCommand.DoIt;
-
- VAR
- r: INTEGER; { Can't use RowNumber or ColumnNumber }
- c: INTEGER; { … because they may be out of range }
- fi: FailInfo;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE PasteCell(aCell: GridCell);
-
- VAR
- sourceCell: TCell;
- replacedCell: TCell;
- destCell: TCell;
-
- BEGIN
- destCell := fCalcDocument.GetCell(aCell.v, aCell.h);
- replacedCell := TCell(destCell.Clone);
- fReplacedCells.InsertLast(replacedCell);
-
- sourceCell := fClipDocument.GetCell(r, c);
- c := c + 1;
- IF c > fClipDocument.fNoOfColumns THEN
- BEGIN
- c := 1;
- r := r + 1;
- IF r > fClipDocument.fNoOfRows THEN
- r := 1;
- END;
-
- destCell.CopyContents(sourceCell); { copy the necessary fields }
- END;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE HdlPasteFailure(error: OSErr;
- message: LONGINT);
- { We ran out of memory and couldn't complete the paste.
- So, let's back out the partial paste. All or nothing! }
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE RestoreCell(replacedCell: TCell);
-
- VAR
- pastedCell: TCell;
-
- BEGIN
- pastedCell := fCalcDocument.GetCell(replacedCell.fRow, replacedCell.fColumn);
- IF replacedCell.IsEmpty THEN { free up memory used by empty cell }
- BEGIN
- fCalcDocument.DeleteCell(pastedCell.fRow, pastedCell.fColumn);
- fCalcDocument.FreeCell(pastedCell);
- END
- ELSE
- pastedCell.CopyContents(replacedCell);
- FreeIfObject(replacedCell); { free up memory used by replacement cell }
- replacedCell := NIL;
- END;
-
- BEGIN
- fReplacedCells.Each(RestoreCell);
- fReplacedCells.DeleteAll;
- UpdateViews;
- END;
-
- BEGIN { TCellPasteCommand.DoIt }
- CatchFailures(fi, HdlPasteFailure);
- r := 1;
- c := 1;
- fCalcDocument.fCellsView.EachSelectedCellDo(PasteCell);
- Success(fi);
- UpdateViews;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellPasteCommand.UndoIt;
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE RestoreCell(replacedCell: TCell);
-
- VAR
- pastedCell: TCell;
-
- BEGIN
- pastedCell := fCalcDocument.GetCell(replacedCell.fRow, replacedCell.fColumn);
- pastedCell.CopyContents(replacedCell);
- END;
-
- BEGIN
- fCalcDocument.fCellsView.ReSelect(fSelection); { restore original selection }
- fReplacedCells.Each(RestoreCell);
- UpdateViews;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellPasteCommand.RedoIt;
-
- VAR
- r: INTEGER; { Can't use RowNumber or ColumnNumber }
- c: INTEGER; { … because they may be out of range }
-
- {--------------------------------------------------------------------------------------------------}
-
- PROCEDURE RepasteCell(aCell: GridCell);
-
- VAR
- sourceCell: TCell;
- destCell: TCell;
-
- BEGIN
- destCell := fCalcDocument.GetCell(aCell.v, aCell.h);
- sourceCell := fClipDocument.GetCell(r, c);
- c := c + 1;
- IF c > fClipDocument.fNoOfColumns THEN
- BEGIN
- c := 1;
- r := r + 1;
- IF r > fClipDocument.fNoOfRows THEN
- r := 1;
- END;
-
- destCell.CopyContents(sourceCell);
- END;
-
- BEGIN
- fCalcDocument.fCellsView.ReSelect(fSelection); { restore original selection }
- r := 1;
- c := 1;
- fCalcDocument.fCellsView.EachSelectedCellDo(RepasteCell);
- UpdateViews;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S ADoCommand}
-
- PROCEDURE TCellPasteCommand.UpdateViews;
-
- VAR
- aString: Str255;
- aCell: GridCell;
-
- BEGIN
- WITH fCalcDocument DO
- BEGIN
- DoRecalculate(NOT kForceAutomatic, kSetDependents);
- fCellsView.InvalidateSelection;
-
- aCell.h := fEditColumn;
- aCell.v := fEditRow;
- IF fCellsView.IsCellSelected(aCell) THEN
- BEGIN
- fEditCell := GetCell(aCell.v, aCell.h);
- fEditCell.GetAsString(aString);
- fEntryView.SetToString(aString);
- END;
- END;
- END;
-
- {--------------------------------------------------------------------------------------------------}
- {$S AFields}
-
- PROCEDURE TCellPasteCommand.Fields(PROCEDURE DoToField(fieldName: Str255;
- fieldAddr: Ptr;
- fieldType: INTEGER)); OVERRIDE;
-
- BEGIN
- DoToField('TCellPasteCommand', NIL, bClass);
- DoToField('fClipDocument', @fClipDocument, bObject);
- DoToField('fCalcDocument', @fCalcDocument, bObject);
- DoToField('fSelection', @fSelection, bRgnHandle);
- DoToField('fReplacedCells', @fReplacedCells, bObject);
- INHERITED Fields(DoToField);
- END;
-